Rename Schunix to SchOS; the kernel becomes SchIFT
Removes the "-unix" element and with it any trademark exposure to The
Open Group.
The split follows the ecosystem layout: SchOS is the system, and the
kernel has its own name. Kernel-identity strings are the only places
that take SchIFT -- uname(2) sysname, /proc/version, and the two licence
sentences that say "kernel" outright. That is what every Unix does here:
`uname -s` on Linux reports the kernel, not the distribution. Everything
a user reads as the product -- panic screen, boot menu, error prefixes,
docs, LICENSE, NOTICE -- is SchOS.
schunix.img is schos.img, the logo assets and the musl TLS patch are
renamed, and __SCHUNIX__ is __SCHOS__ (the define and the patch that
consumes it moved together).
Two things the rename broke, both found by the bootcheck suite:
- shmtest wrote "SCHUNIX-MMAP-OK" with a hardcoded length of 15 and
compared it back by hand-counted offsets (m[3]=='U', m[14]=='K').
The shorter marker left the write running two bytes past the literal
and the compare reading past the data, failing a file-backed mmap
that was working correctly. Now written and compared through one
constant with sizeof.
- bootcheck asserted a 31-byte file after appending to
"hello-from-schunix"; the shorter string makes it 29.
Both are the same mistake: a string literal whose length is written out
somewhere else. Full suite green -- base, Tty, Ps, Sock, Fb, Usb, Evdev.
4
.gitignore
vendored
|
|
@ -1,7 +1,7 @@
|
|||
# Build output. Everything here is reproducible from `make`.
|
||||
build/
|
||||
schunix.img
|
||||
schunix.iso
|
||||
schos.img
|
||||
schos.iso
|
||||
*.o
|
||||
*.d
|
||||
*.asm
|
||||
|
|
|
|||
BIN
Assets/SchOS Full Logo.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
138
Assets/SchOS Full Logo.svg
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1080"
|
||||
viewBox="0 0 1920 1080"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4.4 (dcaf3e7, 2026-05-05)"
|
||||
sodipodi:docname="SchOS Full Logo.svg"
|
||||
inkscape:export-filename="SchOS Full Logo.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:zoom="0.68489583"
|
||||
inkscape:cx="960"
|
||||
inkscape:cy="516.13688"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g8" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<rect
|
||||
x="-11.054408"
|
||||
y="184.24013"
|
||||
width="818.02616"
|
||||
height="644.84044"
|
||||
id="rect9" />
|
||||
<linearGradient
|
||||
id="linearGradient2"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2" />
|
||||
<stop
|
||||
style="stop-color:#949494;stop-opacity:1;"
|
||||
offset="0.20117648"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#454545;stop-opacity:1;"
|
||||
offset="0.50764704"
|
||||
id="stop5" />
|
||||
<stop
|
||||
style="stop-color:#808080;stop-opacity:1;"
|
||||
offset="0.78088236"
|
||||
id="stop9" />
|
||||
<stop
|
||||
style="stop-color:#363636;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#c9c9c9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6" />
|
||||
<stop
|
||||
style="stop-color:#636363;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop8" />
|
||||
<stop
|
||||
style="stop-color:#a2a2a2;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5"
|
||||
id="linearGradient7"
|
||||
x1="354.53467"
|
||||
y1="585.88361"
|
||||
x2="968.30945"
|
||||
y2="585.88361"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.9035284,0,0,1.9035284,85.366084,-529.36246)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2"
|
||||
id="linearGradient3"
|
||||
x1="502.47748"
|
||||
y1="461.89429"
|
||||
x2="822.14758"
|
||||
y2="730.12933"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.9035284,0,0,1.9035284,85.366084,-529.36246)" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="logo"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="matrix(0.9235878,0,0,0.9235878,-243.88631,0.4743235)">
|
||||
<g
|
||||
id="g8"
|
||||
inkscape:label="SmallLogo">
|
||||
<g
|
||||
id="text1"
|
||||
style="font-size:426.811px;line-height:0.8;font-family:miracode;-inkscape-font-specification:miracode;text-align:center;text-anchor:middle;fill:url(#linearGradient3);stroke-width:22.2296;paint-order:markers fill stroke"
|
||||
aria-label="Sch OS"
|
||||
inkscape:label="1">
|
||||
<path
|
||||
d="m 1163.8119,274.38449 10.3739,10.37388 v 14.81982 l -10.3739,10.37388 h -7.4099 -7.4099 -40.0135 -47.4235 -40.0135 l -29.63964,29.63965 29.63964,29.63966 h 40.0135 40.0136 7.4099 7.4099 l 5.1869,5.18694 5.187,5.18694 37.0495,37.04956 5.187,5.18694 5.1869,5.18694 v 7.40991 7.40992 40.01353 40.01353 7.40991 7.40992 l -5.1869,5.18694 -5.187,5.18694 -37.0495,37.04956 -5.187,5.18694 -5.1869,5.18694 h -7.4099 -7.4099 -40.0136 -40.0135 -7.4099 -7.4099 l -5.187,-5.18694 -5.18689,-5.18694 -37.04957,-37.04956 -5.18694,-5.18694 -5.18694,-5.18694 v -14.81983 l 10.37388,-10.37388 h 14.81983 l 5.18694,5.18694 5.18694,5.18694 37.04955,37.04957 h 40.0135 40.0136 l 37.0495,-37.04957 v -40.01353 -40.01353 l -37.0495,-37.04957 h -40.0136 -40.0135 -7.4099 -7.4099 l -5.187,-5.18694 -5.18689,-5.18694 -37.04957,-37.04956 -5.18694,-5.18694 -5.18694,-5.18694 v -14.81983 l 5.18694,-5.18694 5.18694,-5.18694 37.04957,-37.04956 5.18689,-5.18694 5.187,-5.18694 h 7.4099 7.4099 40.0135 47.4235 40.0135 7.4099 z m 284.5405,237.11722 10.3738,10.37388 v 14.81983 l -5.1869,5.18694 -5.1869,5.18694 -37.0496,37.04956 -5.187,5.18694 -5.1869,5.18694 h -7.4099 -7.4099 -40.0136 -40.0135 -7.4099 -7.4099 l -5.1869,-5.18694 -5.187,-5.18694 -37.0496,-37.04956 -5.1869,-5.18694 -5.1869,-5.18694 v -7.40992 -7.40991 -40.01353 -40.01353 -7.40992 -7.40991 l 5.1869,-5.18694 5.1869,-5.18694 37.0496,-37.04956 5.187,-5.18694 5.1869,-5.18694 h 7.4099 7.4099 40.0135 40.0136 7.4099 7.4099 l 5.1869,5.18694 5.187,5.18694 37.0496,37.04956 5.1869,5.18694 5.1869,5.18694 v 14.81983 l -10.3738,10.37388 h -14.8199 l -5.1869,-5.18694 -5.187,-5.18694 -37.0495,-37.04957 h -40.0136 -40.0135 l -37.0495,37.04957 v 40.01353 40.01353 l 37.0495,37.04957 h 40.0135 40.0136 l 37.0495,-37.04957 5.187,-5.18694 5.1869,-5.18694 z m 94.8466,-237.11722 10.3739,10.37388 v 7.40991 7.40991 40.01353 47.42345 47.42344 4.44595 l 11.8558,-11.85586 5.187,-5.18694 5.1869,-5.18694 37.0496,-37.04956 5.1869,-5.18694 5.1869,-5.18694 h 7.41 7.4099 32.6036 7.4099 7.4099 l 5.187,5.18694 5.1869,5.18694 37.0496,37.04956 5.1869,5.18694 5.1869,5.18694 v 7.40991 7.40992 40.01353 47.42344 40.01354 7.40991 7.40991 l -10.3738,10.37388 h -14.8199 l -10.3738,-10.37388 v -7.40991 -7.40991 -40.01354 -47.42344 -40.01353 l -37.0496,-37.04957 h -32.6036 l -37.0496,37.04957 -5.1869,5.18694 -5.187,5.18694 -37.0495,37.04956 v 40.01353 40.01354 7.40991 7.40991 l -10.3739,10.37388 h -14.8198 l -10.3739,-10.37388 v -7.40991 -7.40991 -40.01354 -40.01353 -7.40991 -7.40991 -40.01354 -47.42344 -47.42345 -40.01353 -7.40991 -7.40991 l 10.3739,-10.37388 z"
|
||||
id="path2"
|
||||
inkscape:label="2" />
|
||||
<path
|
||||
d="m 1203.8253,615.8333 h 40.0136 7.4099 7.4099 l 5.1869,5.18694 5.187,5.18693 37.0495,37.04957 5.187,5.18694 5.1869,5.18694 v 7.40991 7.40992 40.01353 47.42344 47.42345 40.01353 7.40991 7.40992 l -5.1869,5.18694 -5.187,5.18693 -37.0495,37.04957 -5.187,5.18694 -5.1869,5.18694 h -7.4099 -7.4099 -40.0136 -40.0135 -7.4099 -7.4099 l -5.187,-5.18694 -5.1869,-5.18694 -37.0496,-37.04957 -5.1869,-5.18693 -5.1869,-5.18694 v -7.40992 -7.40991 -40.01353 -47.42345 -47.42344 -40.01353 -7.40992 -7.40991 l 5.1869,-5.18694 5.1869,-5.18694 37.0496,-37.04957 5.1869,-5.18693 5.187,-5.18694 h 7.4099 7.4099 z m 0,35.56758 h -40.0135 l -37.0496,37.04957 v 40.01353 47.42344 47.42345 40.01353 l 37.0496,37.04957 h 40.0135 40.0136 l 37.0495,-37.04957 v -40.01353 -47.42345 -47.42344 -40.01353 l -37.0495,-37.04957 z m 386.7973,-35.56758 10.3738,10.37387 V 641.027 l -10.3738,10.37388 h -7.41 -7.4099 -40.0135 -47.4235 -40.0135 l -29.6396,29.63965 29.6396,29.63966 h 40.0135 40.0136 7.4099 7.4099 l 5.1869,5.18694 5.187,5.18693 37.0496,37.04957 5.1869,5.18694 5.1869,5.18694 v 7.40991 7.40992 40.01353 40.01353 7.40991 7.40992 l -5.1869,5.18694 -5.1869,5.18693 -37.0496,37.04957 -5.187,5.18694 -5.1869,5.18694 h -7.4099 -7.4099 -40.0136 -40.0135 -7.4099 -7.4099 l -5.1869,-5.18694 -5.187,-5.18694 -37.0496,-37.04957 -5.1869,-5.18693 -5.1869,-5.18694 V 863.3244 l 10.3738,-10.37388 h 14.8199 l 5.1869,5.18694 5.187,5.18694 37.0495,37.04957 h 40.0135 40.0136 l 37.0495,-37.04957 v -40.01353 -40.01353 l -37.0495,-37.04957 h -40.0136 -40.0135 -7.4099 -7.4099 l -5.1869,-5.18694 -5.187,-5.18694 -37.0496,-37.04957 -5.1869,-5.18693 -5.1869,-5.18694 v -14.81983 l 5.1869,-5.18694 5.1869,-5.18694 37.0496,-37.04957 5.187,-5.18693 5.1869,-5.18694 h 7.4099 7.4099 40.0135 47.4235 40.0135 7.4099 z"
|
||||
id="path3"
|
||||
inkscape:label="1" />
|
||||
</g>
|
||||
<path
|
||||
id="path1"
|
||||
style="fill:none;stroke:url(#linearGradient7);stroke-width:67.0141;paint-order:markers fill stroke"
|
||||
d="m 1895.0629,585.88361 c 0,304.12212 -246.5396,550.66179 -550.6618,550.66179 -304.1222,0 -550.66125,-246.53967 -550.66125,-550.66179 0,-304.12212 246.53905,-550.661802 550.66125,-550.661802 208.3753,0 389.7181,115.740002 483.2487,286.440342 42.9766,78.43538 67.4131,168.47469 67.4131,264.22146 z"
|
||||
sodipodi:nodetypes="ssssss"
|
||||
inkscape:label="2" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
BIN
Assets/SchOS Text Logo.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
130
Assets/SchOS Text Logo.svg
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="1920"
|
||||
height="1080"
|
||||
viewBox="0 0 1920 1080"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4.4 (dcaf3e7, 2026-05-05)"
|
||||
sodipodi:docname="Schunix Small Logo.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
inkscape:zoom="0.54276993"
|
||||
inkscape:cx="982.92107"
|
||||
inkscape:cy="614.44082"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<linearGradient
|
||||
id="linearGradient5"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#c9c9c9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6" />
|
||||
<stop
|
||||
style="stop-color:#636363;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop8" />
|
||||
<stop
|
||||
style="stop-color:#a2a2a2;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#444444;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop1" />
|
||||
<stop
|
||||
style="stop-color:#b2b2b2;stop-opacity:1;"
|
||||
offset="0.25"
|
||||
id="stop5" />
|
||||
<stop
|
||||
style="stop-color:#909090;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop3" />
|
||||
<stop
|
||||
style="stop-color:#4c4c4c;stop-opacity:1;"
|
||||
offset="0.75"
|
||||
id="stop4" />
|
||||
<stop
|
||||
style="stop-color:#808080;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient2"
|
||||
x1="480.19177"
|
||||
y1="439.3587"
|
||||
x2="819.08807"
|
||||
y2="723.7265"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5"
|
||||
id="linearGradient7"
|
||||
x1="354.53467"
|
||||
y1="585.88361"
|
||||
x2="968.30945"
|
||||
y2="585.88361"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="logo"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="matrix(0.9235878,0,0,0.9235878,-243.88631,0.4743235)">
|
||||
<g
|
||||
id="g8"
|
||||
inkscape:label="SmallLogo"
|
||||
transform="matrix(1.8840278,0,0,1.8840278,58.429052,-517.93737)">
|
||||
<path
|
||||
id="path1"
|
||||
style="fill:none;stroke:url(#linearGradient7);stroke-width:35.2052;paint-order:markers fill stroke"
|
||||
d="m 950.70685,585.88361 c 0,159.76758 -129.51721,289.28479 -289.28479,289.28479 -159.76758,0 -289.28479,-129.51721 -289.28479,-289.28479 0,-159.76758 129.51721,-289.28479 289.28479,-289.28479 109.46795,0 204.73463,60.80288 253.87001,150.47863 22.5773,41.20526 35.41478,88.50653 35.41478,138.80616 z"
|
||||
sodipodi:nodetypes="ssssss"
|
||||
inkscape:label="2" />
|
||||
<path
|
||||
d="m 614.91693,442.64998 9.0023,9.00229 v 12.86042 l -9.0023,9.00229 h -6.4302 -6.43021 -34.72313 -41.15333 -34.72313 l -25.72083,25.72083 25.72083,25.72084 h 34.72313 34.72312 6.43021 6.43021 l 4.50115,4.50114 4.50114,4.50115 32.15104,32.15104 4.50115,4.50115 4.50115,4.50114 v 6.43021 6.43021 34.72312 34.72313 6.43021 6.43021 l -4.50115,4.50114 -4.50115,4.50115 -32.15104,32.15104 -4.50114,4.50115 -4.50115,4.50114 h -6.43021 -6.43021 -34.72312 -34.72313 -6.43021 -6.4302 l -4.50115,-4.50114 -4.50115,-4.50115 -32.15104,-32.15104 -4.50114,-4.50115 -4.50115,-4.50114 v -12.86042 l 9.00229,-9.00229 h 12.86042 l 4.50115,4.50114 4.50114,4.50115 32.15104,32.15104 h 34.72313 34.72312 l 32.15105,-32.15104 v -34.72313 -34.72312 l -32.15105,-32.15104 h -34.72312 -34.72313 -6.43021 -6.4302 l -4.50115,-4.50115 -4.50115,-4.50114 -32.15104,-32.15105 -4.50114,-4.50114 -4.50115,-4.50115 V 492.8056 l 4.50115,-4.50114 4.50114,-4.50115 32.15104,-32.15104 4.50115,-4.50115 4.50115,-4.50114 h 6.4302 6.43021 34.72313 41.15333 34.72313 6.43021 z m 246.91977,0 9.0023,9.00229 v 12.86042 l -4.50115,4.50114 -4.50115,4.50115 -32.15104,32.15104 -4.50114,4.50115 -4.50115,4.50114 -25.72083,25.72084 25.72083,25.72083 4.50115,4.50115 4.50114,4.50114 32.15104,32.15104 4.50115,4.50115 4.50115,4.50115 v 6.4302 6.43021 34.72313 34.72312 6.43021 6.43021 l -9.0023,9.00229 h -12.86041 l -9.00229,-9.00229 v -6.43021 -6.43021 -34.72312 -34.72313 l -32.15105,-32.15104 -4.50114,-4.50115 -4.50115,-4.50114 -25.72083,-25.72083 -25.72084,25.72083 -4.50114,4.50114 -4.50115,4.50115 -32.15104,32.15104 v 34.72313 34.72312 6.43021 6.43021 l -9.00229,9.00229 h -12.86042 l -9.00229,-9.00229 v -6.43021 -6.43021 -34.72312 -34.72313 -6.43021 -6.4302 l 4.50115,-4.50115 4.50114,-4.50115 32.15104,-32.15104 4.50115,-4.50114 4.50115,-4.50115 25.72083,-25.72083 -25.72083,-25.72084 -4.50115,-4.50114 -4.50115,-4.50115 -32.15104,-32.15104 -4.50114,-4.50115 -4.50115,-4.50114 v -12.86042 l 9.00229,-9.00229 h 12.86042 l 4.50114,4.50114 4.50115,4.50115 32.15104,32.15104 4.50115,4.50115 4.50114,4.50114 25.72084,25.72084 25.72083,-25.72084 4.50115,-4.50114 4.50114,-4.50115 32.15105,-32.15104 4.50114,-4.50115 4.50115,-4.50114 z"
|
||||
id="text1"
|
||||
style="font-size:370.38px;font-family:miracode;-inkscape-font-specification:miracode;text-align:center;text-anchor:middle;fill:url(#linearGradient2);stroke-width:11.801;paint-order:markers fill stroke"
|
||||
aria-label="SX"
|
||||
inkscape:label="1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
2
LICENSE
|
|
@ -181,7 +181,7 @@
|
|||
removed. Third-party software redistributed in a built image -- musl,
|
||||
toybox and mksh, all under ports/ -- keeps its own license; see NOTICE.
|
||||
|
||||
Which outside code may be copied into Schunix and which may not -- the
|
||||
Which outside code may be copied into SchOS and which may not -- the
|
||||
BSD/GPL rules, the NetBSD advertising clause, and what is deliberately
|
||||
never shipped -- is written up in docs/licensing.md. Read it before
|
||||
copying anyone else's code in.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
The Schunix kernel is a derivative work of xv6, which carries the licence
|
||||
The SchIFT kernel is a derivative work of xv6, which carries the licence
|
||||
below. The MIT licence requires this notice be preserved in all copies and
|
||||
substantial portions of the software, so this file must survive any future
|
||||
change to the Schunix licence. See NOTICE and docs/licensing.md.
|
||||
change to the SchOS licence. See NOTICE and docs/licensing.md.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
42
Makefile
|
|
@ -277,16 +277,16 @@ endif
|
|||
# -----------------------------------------------------------------------
|
||||
# Top-level targets
|
||||
# -----------------------------------------------------------------------
|
||||
all: schunix.img
|
||||
all: schos.img
|
||||
|
||||
schunix.img: $(BUILD)/boot/bootblock $(BUILD)/boot/stage2 $(BUILD)/kernel/kernel $(BUILD)/schfs.img
|
||||
dd if=/dev/zero of=schunix.img count=10000
|
||||
dd if=$(BUILD)/boot/bootblock of=schunix.img conv=notrunc
|
||||
dd if=$(BUILD)/boot/stage2 of=schunix.img seek=1 conv=notrunc
|
||||
schos.img: $(BUILD)/boot/bootblock $(BUILD)/boot/stage2 $(BUILD)/kernel/kernel $(BUILD)/schfs.img
|
||||
dd if=/dev/zero of=schos.img count=10000
|
||||
dd if=$(BUILD)/boot/bootblock of=schos.img conv=notrunc
|
||||
dd if=$(BUILD)/boot/stage2 of=schos.img seek=1 conv=notrunc
|
||||
# seek is 1 + STAGE2_SECTORS, not a literal. It was 25 against a 24-sector
|
||||
# stage2; raising STAGE2_SECTORS for the boot logo without touching it wrote
|
||||
# the kernel straight over stage2's own tail.
|
||||
dd if=$(BUILD)/kernel/kernel of=schunix.img seek=$$(( 1 + $(STAGE2_SECTORS) )) conv=notrunc
|
||||
dd if=$(BUILD)/kernel/kernel of=schos.img seek=$$(( 1 + $(STAGE2_SECTORS) )) conv=notrunc
|
||||
|
||||
kernel: $(BUILD)/kernel/kernel
|
||||
|
||||
|
|
@ -315,17 +315,17 @@ ports:
|
|||
# -----------------------------------------------------------------------
|
||||
iso:
|
||||
rm -rf $(BUILD)/kernel $(BUILD)/lib $(BUILD)/cmd
|
||||
$(MAKE) RAMROOT=1 schunix.iso
|
||||
$(MAKE) RAMROOT=1 schos.iso
|
||||
|
||||
schunix.iso: $(BUILD)/boot/cdboot $(BUILD)/boot/stage2 $(BUILD)/kernel/kernel
|
||||
schos.iso: $(BUILD)/boot/cdboot $(BUILD)/boot/stage2 $(BUILD)/kernel/kernel
|
||||
STAGE2_SECTORS=$(STAGE2_SECTORS) sh tools/mkiso.sh $@
|
||||
|
||||
# Boot the ISO the way a machine booting off a disc would: no hard disk at
|
||||
# all, so a kernel that still secretly depends on one fails here rather than
|
||||
# in someone's optical drive.
|
||||
qemu-iso: schunix.iso
|
||||
qemu-iso: schos.iso
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) -cpu qemu64,+rdtscp \
|
||||
-cdrom schunix.iso -boot d \
|
||||
-cdrom schos.iso -boot d \
|
||||
-m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
|
@ -665,10 +665,10 @@ $(BUILD)/sysroot.stamp: sysroot-install
|
|||
|
||||
$(BUILD)/fs.img: $(MKFS) $(BUILD)/sysroot.stamp
|
||||
@mkdir -p $(BUILD)
|
||||
@echo "Creating Schunix File System Image..."
|
||||
@echo "Creating SchOS File System Image..."
|
||||
@# A running QEMU holds this file open, and on Windows that makes rm fail
|
||||
@# with "Device or resource busy" -- which stops the build *after* the
|
||||
@# kernel has already relinked, leaving schunix.img stale. The next test run
|
||||
@# kernel has already relinked, leaving schos.img stale. The next test run
|
||||
@# then boots the previous kernel and the change appears to have done
|
||||
@# nothing, which has cost several debugging cycles. Say so plainly.
|
||||
@rm -f $@ || { \
|
||||
|
|
@ -684,9 +684,9 @@ $(BUILD)/fs.img: $(MKFS) $(BUILD)/sysroot.stamp
|
|||
# -----------------------------------------------------------------------
|
||||
# QEMU
|
||||
# -----------------------------------------------------------------------
|
||||
qemu: schunix.img $(BUILD)/schfs.img
|
||||
qemu: schos.img $(BUILD)/schfs.img
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) -cpu qemu64,+rdtscp \
|
||||
-hda schunix.img -hdb $(BUILD)/schfs.img \
|
||||
-hda schos.img -hdb $(BUILD)/schfs.img \
|
||||
-m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
# The root filesystem. Built from the staged sysroot; the kernel mounts it as
|
||||
|
|
@ -694,7 +694,7 @@ qemu: schunix.img $(BUILD)/schfs.img
|
|||
$(BUILD)/schfs.img: $(MKSCHFS) $(BUILD)/sysroot.stamp
|
||||
@mkdir -p $(BUILD)
|
||||
@rm -f $@
|
||||
./$(MKSCHFS) $@ --size 8000 --label schunix --sysroot $(SYSROOT)
|
||||
./$(MKSCHFS) $@ --size 8000 --label schos --sysroot $(SYSROOT)
|
||||
|
||||
# Boot with a SchFS volume attached as the second disk.
|
||||
#
|
||||
|
|
@ -705,15 +705,15 @@ $(BUILD)/schfs.img: $(MKSCHFS) $(BUILD)/sysroot.stamp
|
|||
# the live v1 root and the SchFS probe correctly finds nothing there.
|
||||
#
|
||||
# Once up: cat /proc/schfs
|
||||
qemu-schfs: schunix.img $(BUILD)/schfs.img
|
||||
qemu-schfs: schos.img $(BUILD)/schfs.img
|
||||
$(QEMU) -serial mon:stdio $(QEMU_DISPLAY) -cpu qemu64,+rdtscp \
|
||||
-hda schunix.img -hdb $(BUILD)/schfs.img \
|
||||
-hda schos.img -hdb $(BUILD)/schfs.img \
|
||||
-m 1G -smp 2 -machine pc-i440fx-9.2
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Misc
|
||||
# -----------------------------------------------------------------------
|
||||
# schunix.img is deliberately NOT here. It is a real file with real
|
||||
# schos.img is deliberately NOT here. It is a real file with real
|
||||
# prerequisites; listing it as phony made make skip the timestamp check and
|
||||
# re-run the four dd commands -- including zeroing five megabytes -- on every
|
||||
# single invocation, including ones where nothing had changed.
|
||||
|
|
@ -721,7 +721,7 @@ qemu-schfs: schunix.img $(BUILD)/schfs.img
|
|||
# derives from art that changes about never, and making it a build dependency
|
||||
# would put Python on the critical path of every clean build for no benefit.
|
||||
# Run this by hand after changing the art.
|
||||
LOGO_SRC = Assets/Schunix Small Logo.png
|
||||
LOGO_SRC = Assets/SchOS Small Logo.png
|
||||
LOGO_PX = 128
|
||||
|
||||
logo:
|
||||
|
|
@ -729,7 +729,7 @@ logo:
|
|||
|
||||
# The USB vendor/product name database, from linux-usb.org.
|
||||
#
|
||||
# Dual-licensed GPL-2.0-or-later **or** 3-clause BSD; Schunix takes the BSD
|
||||
# Dual-licensed GPL-2.0-or-later **or** 3-clause BSD; SchOS takes the BSD
|
||||
# option, which is what makes it usable at all. See NOTICE.
|
||||
#
|
||||
# Cached in dist/ and refreshed only when you ask, NOT on every build. That was
|
||||
|
|
@ -789,7 +789,7 @@ qrcheck: $(QRTEST)
|
|||
# 'clean' removes generated output only. dist/ (upstream tarballs) survives,
|
||||
# so a rebuild never needs the network.
|
||||
clean:
|
||||
rm -rf $(BUILD) schunix.img schunix.iso kernel/arch/x86_64/vectors.S
|
||||
rm -rf $(BUILD) schos.img schos.iso kernel/arch/x86_64/vectors.S
|
||||
|
||||
distclean: clean
|
||||
rm -rf dist
|
||||
|
|
|
|||
22
NOTICE
|
|
@ -1,16 +1,16 @@
|
|||
Schunix
|
||||
SchOS
|
||||
Copyright 2026 Nexoniarz
|
||||
|
||||
This product includes software developed as part of the Schunix project,
|
||||
This product includes software developed as part of the SchOS project,
|
||||
licensed under the Apache License, Version 2.0. See LICENSE.
|
||||
|
||||
================================================================================
|
||||
Third-party software
|
||||
================================================================================
|
||||
|
||||
Schunix incorporates and redistributes software written by others. Their
|
||||
licences apply to their code and are NOT superseded by the Schunix licence.
|
||||
A built Schunix image contains binaries derived from all of the following.
|
||||
SchOS incorporates and redistributes software written by others. Their
|
||||
licences apply to their code and are NOT superseded by the SchOS licence.
|
||||
A built SchOS image contains binaries derived from all of the following.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
xv6-x86_64 / xv6 MIT License
|
||||
|
|
@ -18,7 +18,7 @@ xv6-x86_64 / xv6 MIT License
|
|||
Copyright (c) 2006-2019 Frans Kaashoek, Robert Morris, Russ Cox,
|
||||
Massachusetts Institute of Technology CSAIL
|
||||
|
||||
The Schunix kernel is a derivative work of xv6. Substantial portions of
|
||||
The SchIFT kernel is a derivative work of xv6. Substantial portions of
|
||||
kernel/ -- notably the process, trap, virtual memory, buffer cache and v1
|
||||
filesystem code -- descend from it, however heavily rewritten. The MIT licence
|
||||
requires that this notice be preserved in all copies; see LICENSE.MIT.
|
||||
|
|
@ -76,7 +76,7 @@ Maintained by Stephen J. Gowdy <linux.usb.ids@gmail.com>
|
|||
http://www.linux-usb.org/usb.ids
|
||||
|
||||
Distributed by its maintainer under the terms of *either* the GNU General
|
||||
Public License version 2 or later, *or* the 3-clause BSD Licence. Schunix takes
|
||||
Public License version 2 or later, *or* the 3-clause BSD Licence. SchOS takes
|
||||
the BSD option; the GPL option is not exercised and could not be, since
|
||||
Apache-2.0 and GPL-2.0-only cannot be combined (see docs/licensing.md section
|
||||
2).
|
||||
|
|
@ -91,7 +91,7 @@ Roboto Apache-2.0
|
|||
Copyright the Roboto Project Authors (https://github.com/googlefonts/roboto)
|
||||
|
||||
Shipped as /usr/share/fonts/Roboto-Regular.ttf, from ports/Roboto. Licensed
|
||||
under Apache-2.0 -- the same licence as Schunix itself, so it carries no
|
||||
under Apache-2.0 -- the same licence as SchOS itself, so it carries no
|
||||
obligation beyond this notice. Intended for the desktop, window manager and
|
||||
compositor.
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ Shipped as /usr/share/fonts/JetBrainsMono-Regular.ttf, from ports/JetBrains_Mono
|
|||
and TTY.
|
||||
|
||||
Under the SIL Open Font License 1.1 the font remains under OFL even inside this
|
||||
Apache-2.0 system -- that does not reach any other part of Schunix -- and it may
|
||||
Apache-2.0 system -- that does not reach any other part of SchOS -- and it may
|
||||
not be sold on its own. Bundling it with an operating system is expressly
|
||||
permitted. JetBrains Mono declares no Reserved Font Name, so a modified version
|
||||
(a pre-rasterised bitmap, for instance) may keep the name.
|
||||
|
|
@ -117,7 +117,7 @@ permitted. JetBrains Mono declares no Reserved Font Name, so a modified version
|
|||
Copyright (c) Qi Ma, Leyi Pan, Ao Sun, Peiran Xu
|
||||
|
||||
kernel/fs/fs.c and parts of tools/mkfs.c derive from this project, which extends
|
||||
xv6's file system with features Schunix still uses today:
|
||||
xv6's file system with features SchOS still uses today:
|
||||
|
||||
- the HTree hashed directory index (BKDRHash, HASHRANGE, the primary/overflow
|
||||
bucket layout), after Daniel Phillips, "A Directory Index for EXT2",
|
||||
|
|
@ -137,7 +137,7 @@ Distinct from xv6 itself (LICENSE.MIT), which this project in turn derives from.
|
|||
================================================================================
|
||||
|
||||
The build downloads upstream tarballs into dist/ and applies the patches in
|
||||
ports/<name>/patches/. Nothing in ports/ is Schunix code; do not add first-party
|
||||
ports/<name>/patches/. Nothing in ports/ is SchOS code; do not add first-party
|
||||
work there. See docs/layout.md.
|
||||
|
||||
Licence questions -- what may be copied in, what may never be, and how to check
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ print16:
|
|||
ret
|
||||
|
||||
bootmsg:
|
||||
.asciz "Schunix booting...\r\n"
|
||||
.asciz "SchOS booting...\r\n"
|
||||
|
||||
.code32
|
||||
start32:
|
||||
|
|
|
|||
|
|
@ -469,8 +469,8 @@ static int
|
|||
boot_menu(void)
|
||||
{
|
||||
const char *items[] = {
|
||||
"Boot Schunix",
|
||||
"Boot Schunix (verbose)",
|
||||
"Boot SchOS",
|
||||
"Boot SchOS (verbose)",
|
||||
"Reboot to firmware setup",
|
||||
};
|
||||
int nitems = 3;
|
||||
|
|
@ -481,7 +481,7 @@ boot_menu(void)
|
|||
|
||||
for (;;) {
|
||||
fill_rect(0, 0, g_width, g_height, SCH_BG);
|
||||
draw_centered(60, "Schunix Boot Manager", SCH_ACCENT);
|
||||
draw_centered(60, "SchOS Boot Manager", SCH_ACCENT);
|
||||
draw_memory_line(84, SCH_DIM);
|
||||
|
||||
for (int i = 0; i < nitems; i++) {
|
||||
|
|
@ -547,7 +547,7 @@ splash(void)
|
|||
|
||||
// The product, not the loader.
|
||||
//
|
||||
// This used to read "Schunix Boot Manager / version 1.0 / Memory: 1023 MB /
|
||||
// This used to read "SchOS Boot Manager / version 1.0 / Memory: 1023 MB /
|
||||
// Press F8 for boot menu...", centred, in gold on purple. Every part of that
|
||||
// is something a system shows its developer rather than its user: the name
|
||||
// of the component doing the work, its version, and a memory figure nobody
|
||||
|
|
@ -605,7 +605,7 @@ stage2main(void)
|
|||
|
||||
if (g_have_fb) {
|
||||
fill_rect(0, 0, g_width, g_height, SCH_BG);
|
||||
draw_string((g_width - 7 * 8) / 2, g_height / 2 - 50, "SCHUNIX", SCH_ACCENT, SCH_BG);
|
||||
draw_string((g_width - 7 * 8) / 2, g_height / 2 - 50, "SCHOS", SCH_ACCENT, SCH_BG);
|
||||
}
|
||||
|
||||
// Booted from a disc we then could not read. Falling through would send
|
||||
|
|
@ -646,7 +646,7 @@ stage2main(void)
|
|||
stosb((void*) hdr->load_end_addr, 0, hdr->bss_end_addr - hdr->load_end_addr);
|
||||
|
||||
if (g_have_fb)
|
||||
progress_label("Starting Schunix...");
|
||||
progress_label("Starting SchOS...");
|
||||
|
||||
// Jump to kernel entry. NOT a normal C call: kernel/arch/x86_64/
|
||||
// entry.S's mboot_entry reads its "argument" (the framebuffer
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Schunix — minimal init (PID 1)
|
||||
// SchOS — minimal init (PID 1)
|
||||
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
|
|
@ -89,7 +89,7 @@ main(void)
|
|||
|
||||
mkdir("/sys");
|
||||
|
||||
xputs(1, "\nSchunix\n");
|
||||
xputs(1, "\nSchOS\n");
|
||||
xputs(1, "init: ready (pid 1)\n");
|
||||
|
||||
for (;;) {
|
||||
|
|
@ -102,7 +102,7 @@ main(void)
|
|||
|
||||
if (pid == 0) {
|
||||
// exec.c auto-enables Linux ABI for musl binaries (entry >= 0x100000).
|
||||
// Do NOT call enable_linux_abi() here — it corrupts Schunix syscall
|
||||
// Do NOT call enable_linux_abi() here — it corrupts SchOS syscall
|
||||
// numbers for the exec/exit calls that follow in this child.
|
||||
// Standardized naming: the shell is always /bin/sh, regardless of
|
||||
// which implementation backs it (dash, mksh, etc.) — no ksh/mksh/
|
||||
|
|
|
|||
|
|
@ -77,19 +77,29 @@ main(void)
|
|||
check(p[100] == 'X', "and so is one further into the segment");
|
||||
|
||||
// --- file-backed mmap --------------------------------------------------
|
||||
// Written and compared through one constant, and never by hand-counted
|
||||
// offsets. Those offsets used to spell out SCHUNIX-MMAP-OK a character at a
|
||||
// time -- m[3]=='U' and m[14]=='K' -- with the length 15 written out
|
||||
// separately. Renaming the marker to SCHOS shortened it to 13 and left both
|
||||
// behind: the write ran two bytes off the end of the literal and the
|
||||
// compare read past the data, which failed a file-backed mmap that was
|
||||
// working correctly.
|
||||
static const char MARK[] = "SCHOS-MMAP-OK";
|
||||
const int MARKLEN = (int)(sizeof(MARK) - 1);
|
||||
|
||||
int fd = open("/tmp/shmtest.dat", O_CREATE | O_RDWR);
|
||||
check(fd >= 0, "created a file to map");
|
||||
if (fd >= 0) {
|
||||
write(fd, "SCHUNIX-MMAP-OK", 15);
|
||||
write(fd, MARK, MARKLEN);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fd = open("/tmp/shmtest.dat", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
char *m = mmap(0, 4096, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
int ok = ((long)m > 0) &&
|
||||
m[0]=='S' && m[1]=='C' && m[2]=='H' && m[3]=='U' &&
|
||||
m[8]=='M' && m[13]=='O' && m[14]=='K';
|
||||
int ok = ((long)m > 0);
|
||||
for (int i = 0; ok && i < MARKLEN; i++)
|
||||
ok = (m[i] == MARK[i]);
|
||||
check(ok, "mmap of a file returns the file, not zeros");
|
||||
close(fd);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ Bringing in toybox (see "Coreutils" below) surfaced four more, all fixed:
|
|||
all (`kernel/sys/linux_abi.c`) — every external command spawn from a
|
||||
program that prefers `vfork()` over `fork()` failed outright. Mapped to
|
||||
the existing `fork()` (a fully correct, if slightly slower, substitute).
|
||||
- `sys_stat`/`fstat`/`fstatat` (`kernel/sys/sys_fs.c`) filled in Schunix's
|
||||
- `sys_stat`/`fstat`/`fstatat` (`kernel/sys/sys_fs.c`) filled in SchOS's
|
||||
own native `struct stat` layout regardless of the caller — musl/toybox
|
||||
parse a fixed Linux ABI byte layout instead, so `st_mode` was garbage and
|
||||
tools like `ls` couldn't tell files from directories, or executables from
|
||||
|
|
@ -110,7 +110,7 @@ programs, pipes, and `ls`/`mkdir`/`grep` without issue.
|
|||
|
||||
## 2. Naming standardization
|
||||
|
||||
Schunix standardizes on exactly one name per role, regardless of the
|
||||
SchOS standardizes on exactly one name per role, regardless of the
|
||||
underlying implementation: the shell is always installed and exec'd as
|
||||
`/bin/sh` (currently mksh, built from `ports/mksh/`), and PID 1 is always
|
||||
`/bin/init`. `cmd/init/main.c`'s exec loop only ever tries `/bin/sh` — no
|
||||
|
|
@ -161,7 +161,7 @@ Split into two stages, the standard way real bootloaders solve this:
|
|||
compiled size, and errors out (like `tools/sign.pl` does for stage 1) if
|
||||
it ever grows past that budget instead of silently corrupting the layout.
|
||||
|
||||
The kernel now starts at disk sector 17 instead of 1 (`schunix.img`'s `dd
|
||||
The kernel now starts at disk sector 17 instead of 1 (`schos.img`'s `dd
|
||||
... seek=17` in the root `Makefile`, and the equivalent `+(1+STAGE2_SECTORS)`
|
||||
in `stage2main.c`'s `readseg()` — all three places that encode
|
||||
`STAGE2_SECTORS` have to agree, or the kernel won't be found on disk at
|
||||
|
|
@ -184,7 +184,7 @@ renderer in `stage2main.c` (not the kernel's `vga.c` — paging isn't set up
|
|||
yet, so the LFB physical address from the VBE block is used as a plain
|
||||
pointer) reusing the kernel's own font data (`include/font.h`) directly.
|
||||
It fills the framebuffer with PSOGM's purple (matching
|
||||
`kernel/core/console.c`'s panic screen) and draws "SCHUNIX" centered, then:
|
||||
`kernel/core/console.c`'s panic screen) and draws "SCHOS" centered, then:
|
||||
|
||||
- **Real-time loading bar**: `readsect()` (in `stage2main.c`, not the
|
||||
kernel) calls `progress_tick()` after every 512-byte disk read, updating
|
||||
|
|
@ -210,7 +210,7 @@ It fills the framebuffer with PSOGM's purple (matching
|
|||
`sys_reboot()`); a real bootloader can't jump into BIOS/UEFI setup
|
||||
directly, so this is the closest honest equivalent — it gives the user
|
||||
a fresh POST during which their firmware's own setup-menu key works.
|
||||
- **Verbose boot**: picking "Boot Schunix (verbose)" writes a flag byte to
|
||||
- **Verbose boot**: picking "Boot SchOS (verbose)" writes a flag byte to
|
||||
`BOOT_VERBOSE_FLAG_ADDR` (`VBE_INFO_ADDR + 0x100`, i.e. just past the VBE
|
||||
block) before jumping to the kernel. `kernel/core/main.c`'s `kmain()`
|
||||
reads it into a global `boot_verbose` as its very first action and, if
|
||||
|
|
@ -496,7 +496,7 @@ became an amber terminal. `include/theme.h` is now the one palette, and the
|
|||
rule is: **normal states are calm and dark; only failure is loud.** PSOGM keeps
|
||||
the purple entirely to itself, which is what makes it mean something.
|
||||
|
||||
The splash copy went from "Schunix Boot Manager / version 1.0 / Memory: 1023 MB
|
||||
The splash copy went from "SchOS Boot Manager / version 1.0 / Memory: 1023 MB
|
||||
/ Press F8 for boot menu..." to the product name, a rule in the accent colour,
|
||||
and the one hint that is actionable — moved to the bottom, where a hint
|
||||
belongs. No shipping OS names its bootloader on the splash.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# SchAPI, and Schunix as a system
|
||||
# SchAPI, and SchOS as a system
|
||||
|
||||
Status: **direction agreed, not yet implemented.** Nothing in this document
|
||||
changes what is being built this week; it changes what everything is being
|
||||
|
|
@ -8,7 +8,7 @@ built *towards*. See §7 for what actually happens now.
|
|||
|
||||
## 1. The decision
|
||||
|
||||
Schunix stops being "a Unix-like kernel with a userland bolted on" and becomes
|
||||
SchOS stops being "a Unix-like kernel with a userland bolted on" and becomes
|
||||
a **system**: a kernel, a native API, and the services and applications that
|
||||
sit on it, designed together.
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ Linux made the opposite choice — the syscall ABI *is* the contract, "we do not
|
|||
break userspace" — and consequently every syscall mistake ever made is still
|
||||
there, with a `2` or a `64` suffixed to the name of its replacement.
|
||||
|
||||
So, for Schunix:
|
||||
So, for SchOS:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────┐
|
||||
|
|
@ -58,7 +58,7 @@ So, for Schunix:
|
|||
├──────────────────────────────────────────────┤
|
||||
│ SchAPI │ POSIX / Linux personality│ ← THE STABLE BOUNDARY
|
||||
├──────────────────┴───────────────────────────┤
|
||||
│ libschunix — the only thing that may syscall│
|
||||
│ libschos — the only thing that may syscall│
|
||||
├──────────────────────────────────────────────┤
|
||||
│ syscall table — PRIVATE, unstable, renumberable
|
||||
├──────────────────────────────────────────────┤
|
||||
|
|
@ -69,11 +69,11 @@ So, for Schunix:
|
|||
Rules that follow, and they are not negotiable if the promise is to hold:
|
||||
|
||||
1. **A program that issues `syscall` directly is unsupported.** It may break at
|
||||
any release. Only `libschunix` may.
|
||||
2. `libschunix` exports versioned symbols. An entry point's behaviour never
|
||||
any release. Only `libschos` may.
|
||||
2. `libschos` exports versioned symbols. An entry point's behaviour never
|
||||
changes; a changed behaviour is a new version of the symbol.
|
||||
3. The kernel may renumber, merge, split or delete syscalls at will, provided
|
||||
`libschunix` still presents the same surface.
|
||||
`libschos` still presents the same surface.
|
||||
|
||||
This *reconciles* with the existing decision to adopt Linux syscall numbering
|
||||
(`docs/roadmap.md`, and the reason musl/toybox/mksh work at all). Linux
|
||||
|
|
@ -98,7 +98,7 @@ Every public interface carries exactly one tier:
|
|||
| `provisional` | Until the next release | Freely |
|
||||
| `internal` | None | Freely, without notice |
|
||||
|
||||
**Everything in Schunix today is `provisional`.** The freeze starts at 1.0 and
|
||||
**Everything in SchOS today is `provisional`.** The freeze starts at 1.0 and
|
||||
covers only what is marked `stable` at that moment. This is not a way of
|
||||
dodging the commitment — it is the only way to make it, because a promise made
|
||||
now would permanently enshrine, among other things, a `fcntl(F_SETFL)` that
|
||||
|
|
@ -164,7 +164,7 @@ reasons that a single tree cannot give:
|
|||
That table is the same lesson §1 of the roadmap already learned the hard way
|
||||
with FreeBSD's `sys/dev/usb`: 100k lines welded to newbus, where porting the
|
||||
USB stack means porting the device framework first. Networking is the same
|
||||
shape. Read FreeBSD, lift NetBSD, write Schunix.
|
||||
shape. Read FreeBSD, lift NetBSD, write SchOS.
|
||||
|
||||
### Licensing — read this before copying anything
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ Ranked by value, not by size:
|
|||
1. **`sys/net`, `sys/netinet` — the TCP/IP stack.** The largest single win
|
||||
available. Phase 2 of the roadmap wants ARP/IPv4/ICMP/UDP/TCP, and this is a
|
||||
mature, clean, readable, 2-clause-heavy implementation of exactly that.
|
||||
2. **`sys/kern/subr_pool.c` — the pool/slab allocator.** Schunix has `kalloc`
|
||||
2. **`sys/kern/subr_pool.c` — the pool/slab allocator.** SchOS has `kalloc`
|
||||
and a page at a time. Every subsystem written since has invented its own
|
||||
fixed-size table to work around that.
|
||||
3. **`autoconf` — the driver framework** (`config(1)`, `cfdriver`/`cfattach`,
|
||||
|
|
@ -203,7 +203,7 @@ relicensed-in-notice, and maintained forever under the §3 promise.
|
|||
Not yet designed. What is decided about it:
|
||||
|
||||
- It is the native interface; POSIX is available beneath it but not the idiom.
|
||||
- It is reached through `libschunix`, never by direct syscall.
|
||||
- It is reached through `libschos`, never by direct syscall.
|
||||
- It is designed *with* Schcom in mind, because a compositor and its clients
|
||||
are the first real users and their needs (IPC, shared buffers, event streams,
|
||||
object lifetimes) are what will shape it.
|
||||
|
|
@ -234,6 +234,6 @@ What this document changes *today* is only this:
|
|||
something to work with at 1.0.
|
||||
3. When the network stack is written, NetBSD's is the starting point rather
|
||||
than a blank file — with the licence check in §5 applied per file.
|
||||
4. `libschunix` is created when there is a second personality to justify it.
|
||||
4. `libschos` is created when there is a second personality to justify it.
|
||||
Until then, the *rule* stands even though the library does not exist yet:
|
||||
no new first-party program issues raw syscalls.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ end to end.
|
|||
## 2. What is deliberately not taken
|
||||
|
||||
- **No ZFS storage pools / RAID-Z / vdevs.** Multi-disk redundancy is a large
|
||||
subsystem that solves a problem Schunix does not have yet.
|
||||
subsystem that solves a problem SchOS does not have yet.
|
||||
- **No btrfs-style rebalancing or online format conversion.** Enormous
|
||||
complexity, and it is the historical source of btrfs's worst bugs.
|
||||
- **No actual SQL.** No parser, no query planner, no relational engine. See §6 —
|
||||
|
|
@ -242,7 +242,7 @@ Phases 1-3 are roughly 3,000-4,000 lines and are the bulk of the work. Phase 1
|
|||
alone (B-tree + torture harness) is worth doing carefully and unhurriedly; every
|
||||
later phase compounds on it.
|
||||
|
||||
This is the largest single piece of work in Schunix. It is also entirely
|
||||
This is the largest single piece of work in SchOS. It is also entirely
|
||||
ordinary filesystem engineering with excellent published references
|
||||
(Giampaolo for BeFS; the btrfs design papers; the ZFS uberblock/checksum-in-
|
||||
parent scheme) — there is no research risk here, only volume.
|
||||
|
|
@ -254,7 +254,7 @@ populate this format. Building it against v1 means building it twice.
|
|||
|
||||
Three different things get called "the limit", and they are worth keeping apart:
|
||||
what the **on-disk format** can express, what **this implementation** can
|
||||
currently mount, and what the **rest of Schunix** can carry. The smallest one is
|
||||
currently mount, and what the **rest of SchOS** can carry. The smallest one is
|
||||
what you actually hit.
|
||||
|
||||
### The format
|
||||
|
|
@ -292,7 +292,7 @@ raising `SCHFS_SPACE_PAGES` to 4096 makes it 512 GiB at 64 KiB of pointers per
|
|||
mount. It is set where it is because the page-pointer vector lives inside
|
||||
`struct schfs_vol`, which the kernel holds as static storage.
|
||||
|
||||
### The rest of Schunix
|
||||
### The rest of SchOS
|
||||
|
||||
These are VFS and driver limits rather than SchFS ones:
|
||||
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ need.
|
|||
|
||||
## 3. Linux drivers
|
||||
|
||||
**Decided 2026-08-08.** Linux drivers are not shipped with Schunix and never
|
||||
**Decided 2026-08-08.** Linux drivers are not shipped with SchOS and never
|
||||
will be. The user may install one on their own machine, through a device
|
||||
manager or equivalent, and Schunix will load it.
|
||||
manager or equivalent, and SchOS will load it.
|
||||
|
||||
The licensing reasoning matters and is worth stating exactly, because it is
|
||||
easy to get wrong in both directions:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ that can't be rebuilt (except upstream tarballs, which live in `dist/` and are
|
|||
deliberately kept out of `clean`).
|
||||
|
||||
```
|
||||
schunix/
|
||||
schos/
|
||||
├─ boot/ Stage 1 MBR + stage 2 loader (splash, F8 menu, kernel load)
|
||||
├─ kernel/ The kernel, by subsystem: arch/ core/ dev/ fs/ proc/ sys/
|
||||
├─ include/ Headers shared by kernel, userland, and tools/mkfs
|
||||
|
|
@ -19,7 +19,7 @@ schunix/
|
|||
│ cmd/<name>/main.c → sysroot/bin/<name>
|
||||
├─ ports/ Third-party software — one directory per port.
|
||||
│ Contains ONLY a Makefile and optional patches/.
|
||||
├─ projects/ Things that run ON Schunix rather than things that ARE it:
|
||||
├─ projects/ Things that run ON SchOS rather than things that ARE it:
|
||||
│ the compositor, window manager, desktop, and installer.
|
||||
│ Not part of the kernel build. See projects/README.md.
|
||||
├─ tools/ Host-side helpers, SOURCE ONLY: mkfs.c, the SchFS test
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# Licensing
|
||||
|
||||
The one page to check before copying anyone else's code into Schunix.
|
||||
The one page to check before copying anyone else's code into SchOS.
|
||||
|
||||
Referenced from `LICENSE`, `LICENSE.MIT` and `NOTICE`, all three of which
|
||||
pointed here long before this file existed.
|
||||
|
||||
---
|
||||
|
||||
## 1. Schunix is Apache-2.0
|
||||
## 1. SchOS is Apache-2.0
|
||||
|
||||
Copyright Nexoniarz. See `LICENSE`.
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ outside contributions, that silence is the expensive kind.
|
|||
|
||||
What that grant means in practice: Apache-2.0 §2 gives everyone a perpetual,
|
||||
worldwide, irrevocable licence to reproduce, modify, sublicense and distribute
|
||||
Schunix. Any additional restriction stated elsewhere — in a README, a website,
|
||||
SchOS. Any additional restriction stated elsewhere — in a README, a website,
|
||||
or a policy — does not narrow it. The licence text is what holds up.
|
||||
|
||||
If restricted distribution is ever genuinely wanted, that is a licence change
|
||||
|
|
@ -57,7 +57,7 @@ licences at once.
|
|||
|
||||
GPL-3.0 fixed this in the other direction (Apache-2.0 is compatible *into*
|
||||
GPLv3), but that does not help: the result would have to ship under GPLv3, and
|
||||
Schunix does not.
|
||||
SchOS does not.
|
||||
|
||||
**Practical consequence:** BSD drivers can be adopted. Linux drivers cannot,
|
||||
ever, no matter how convenient. This is why the USB stack was written from the
|
||||
|
|
@ -113,7 +113,7 @@ sys/netinet6 51 files, 5 " " "
|
|||
```
|
||||
|
||||
Encouraging at first glance — the 25 in `sys/netinet` are almost all SCTP,
|
||||
DCCP and multicast routing, none of which Schunix needs. `ip_input.c`,
|
||||
DCCP and multicast routing, none of which SchOS needs. `ip_input.c`,
|
||||
`ip_output.c`, `udp_usrreq.c`, `if_arp.c`, `ip_icmp.c`, `if.c` and `route.c`
|
||||
are all UC 3-clause, i.e. fine.
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ tables and FreeBSD's locking. Taking it means porting FreeBSD's kernel
|
|||
infrastructure first and finding the TCP somewhere underneath, which is the same
|
||||
conclusion `docs/roadmap.md` §1 already reached about `sys/dev/usb`.
|
||||
|
||||
lwIP was written for the case Schunix is in: a small operating system with a raw
|
||||
lwIP was written for the case SchOS is in: a small operating system with a raw
|
||||
Ethernet driver and no infrastructure to speak of. Its port layer is a handful
|
||||
of files, it has no dependency on the host kernel's allocator or locking, and it
|
||||
brings ARP, IPv4, ICMP, UDP, TCP, DHCP and DNS.
|
||||
|
|
@ -175,7 +175,7 @@ Chosen 2026-08-09, both licences checked at source rather than assumed:
|
|||
| Roboto | desktop, window manager, compositor | **Apache-2.0** |
|
||||
| JetBrains Mono | terminal, TTY | **SIL OFL 1.1** |
|
||||
|
||||
Roboto is the same licence as Schunix, so it is the easy case: a NOTICE entry
|
||||
Roboto is the same licence as SchOS, so it is the easy case: a NOTICE entry
|
||||
and nothing else.
|
||||
|
||||
OFL is permissive and bundling is precisely what it is for, with two conditions
|
||||
|
|
@ -195,7 +195,7 @@ worth knowing before anyone subsets or converts a font:
|
|||
## 4. Things that are deliberately not shipped
|
||||
|
||||
Some code is fine to *build and run locally* and impossible to *distribute*
|
||||
with Schunix. Keeping the distinction sharp is what stops it eroding:
|
||||
with SchOS. Keeping the distinction sharp is what stops it eroding:
|
||||
|
||||
- **`Refrence/`** — a FreeBSD checkout (`Refrence/freebsd-src`), kept as
|
||||
reference material and a parts bin. Never built, never in an image. The
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ plus an installer and a `.sip` package format.
|
|||
This file records two things that are easy to lose: the *order* the work has
|
||||
to happen in, and the decisions that constrain it.
|
||||
|
||||
**Superseded in direction, not in order.** Schunix is now aimed at being a
|
||||
**Superseded in direction, not in order.** SchOS is now aimed at being a
|
||||
*system* rather than a Unix-like kernel with a userland attached: a NeXTSTEP/
|
||||
macOS-shaped layering, with POSIX kept complete but demoted from identity to
|
||||
personality, and a native API (**SchAPI**) above it. See
|
||||
|
|
@ -189,7 +189,7 @@ width text is not a font change, it is a text-rendering layer.
|
|||
as-is if wanted; writing one is also reasonable and more interesting
|
||||
- [ ] **The typefaces, decided 2026-08-09.** Both verified, not assumed:
|
||||
**Roboto** for the desktop, window manager and compositor --
|
||||
**Apache-2.0**, the same licence as Schunix, so it needs nothing beyond a
|
||||
**Apache-2.0**, the same licence as SchOS, so it needs nothing beyond a
|
||||
NOTICE entry.
|
||||
**JetBrains Mono** for the terminal and TTY -- **SIL OFL 1.1**, and
|
||||
notably with *no* Reserved Font Name declared, so it may be modified and
|
||||
|
|
@ -205,7 +205,7 @@ width text is not a font change, it is a text-rendering layer.
|
|||
**Font licensing: public domain or very permissive only.** No SIL OFL if it
|
||||
can be avoided, no "free for personal use", no CC-BY-SA. The constraint is
|
||||
the same one that governs drivers (§1): a font file is redistributed inside
|
||||
every Schunix image, so its licence attaches to the image.
|
||||
every SchOS image, so its licence attaches to the image.
|
||||
|
||||
Safe choices, in rough order of usefulness:
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ key-down/key-up with modifiers and no line discipline at all — an evdev-style
|
|||
|
||||
### Phase 6 — Installer and `.sip`
|
||||
|
||||
`.sip` (Schunix Installation Package), the stated model being WIM in Windows
|
||||
`.sip` (SchOS Installation Package), the stated model being WIM in Windows
|
||||
PE: a *file-based* image rather than a block image, so one file can hold a
|
||||
whole filesystem, be applied to a partition of any size, and hold several
|
||||
images that share their common files.
|
||||
|
|
@ -301,7 +301,7 @@ sysvinit is not the config format, it is *demand launching*: launchd holds the
|
|||
listening socket or watches the path, and starts the job when something actually
|
||||
arrives. That inverts the dependency graph — jobs stop needing to declare what
|
||||
must start before them, because the thing they depend on answers on first use.
|
||||
Schunix already has the two pieces that makes possible: `AF_UNIX` sockets
|
||||
SchOS already has the two pieces that makes possible: `AF_UNIX` sockets
|
||||
(`kernel/net/unix.c`) and a real `/proc`. What is missing is a supervisor that
|
||||
can hold a socket on a job's behalf and hand it over on exec, plus a job
|
||||
description format. Prerequisite for this being worth anything: `ps` and `top`
|
||||
|
|
@ -360,7 +360,7 @@ palette and a layout, none of which care how the pixels were found. What does
|
|||
not survive is every assumption in `stage2main.c` about where things live in low
|
||||
memory (see `docs/layout.md`).
|
||||
|
||||
### SchFS beyond Schunix
|
||||
### SchFS beyond SchOS
|
||||
|
||||
Three ideas parked 2026-08-08, in the order they should happen.
|
||||
|
||||
|
|
@ -447,7 +447,7 @@ Three details worth keeping:
|
|||
- The ceiling is **3 GB**, because `kvmalloc()` maps 0–4 GB as four 1 GB pages
|
||||
and marks the top one uncached for PCI BARs.
|
||||
- Below `PHYSTOP_MIN` it prints why and stops, rather than triple faulting in
|
||||
silence. At 24 MB: `e820: only 23 MB usable; Schunix needs at least 24 MB`.
|
||||
silence. At 24 MB: `e820: only 23 MB usable; SchOS needs at least 24 MB`.
|
||||
|
||||
The original text is kept below because the reasoning still applies to the SMP
|
||||
half of §3b, which is the same shape of bug: a constant nobody revisited.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Error numbers, matching the Linux x86_64 ABI values so that musl-linked
|
||||
// programs interpret syscall failures correctly. Kernel code returns these
|
||||
// negated (e.g. `return -ENOSYS;`), exactly like Linux does internally.
|
||||
#ifndef SCHUNIX_ERRNO_H
|
||||
#define SCHUNIX_ERRNO_H
|
||||
#ifndef SCHOS_ERRNO_H
|
||||
#define SCHOS_ERRNO_H
|
||||
|
||||
#define EPERM 1 // Operation not permitted
|
||||
#define ENOENT 2 // No such file or directory
|
||||
|
|
@ -57,4 +57,4 @@
|
|||
#define ENOTCONN 107 // Transport endpoint is not connected
|
||||
#define ECONNREFUSED 111 // Connection refused
|
||||
|
||||
#endif // SCHUNIX_ERRNO_H
|
||||
#endif // SCHOS_ERRNO_H
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// Framebuffer device ABI -- /dev/fb0.
|
||||
//
|
||||
// These are Linux's fbdev request numbers and structure layouts, not ours.
|
||||
// Schunix invented this device, so nothing forced the choice; matching Linux
|
||||
// SchOS invented this device, so nothing forced the choice; matching Linux
|
||||
// was still the right one. A framebuffer is the first thing a graphics
|
||||
// program looks for, and every such program already knows how to ask
|
||||
// FBIOGET_VSCREENINFO. Inventing a private struct would have meant patching
|
||||
|
|
@ -76,7 +76,7 @@ struct fb_var_screeninfo {
|
|||
};
|
||||
|
||||
struct fb_fix_screeninfo {
|
||||
char id[16]; // "schunixfb"
|
||||
char id[16]; // "schosfb"
|
||||
unsigned long smem_start; // physical address of the framebuffer
|
||||
unsigned int smem_len; // its length in bytes
|
||||
unsigned int type;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
// the userland is built against a libc that sends Linux flag values, and the
|
||||
// kernel reads them with these constants. They disagreed for a long time, with
|
||||
// results that looked like filesystem corruption rather than like a mistake --
|
||||
// Linux O_APPEND (0x400) landed on Schunix's O_TRUNC, so `cmd >> file`
|
||||
// Linux O_APPEND (0x400) landed on SchOS's O_TRUNC, so `cmd >> file`
|
||||
// truncated the file it was meant to extend, and Linux O_TRUNC (0x200) landed
|
||||
// on O_CREATE, so `cmd > file` left whatever was past the new end in place.
|
||||
// Neither failure pointed anywhere near a header.
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
#define O_NOFOLLOW 0x020000 /* Linux O_NOFOLLOW (0400000) */
|
||||
#define O_CLOEXEC 0x080000 /* Linux O_CLOEXEC (02000000) */
|
||||
|
||||
// Schunix-only, placed above every flag Linux defines so it can never be
|
||||
// SchOS-only, placed above every flag Linux defines so it can never be
|
||||
// mistaken for one. 0x40000 was used before and collides with Linux O_NOATIME.
|
||||
#define O_EXTENT 0x8000000 /* sparse-extent hint */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Schunix OS System Font - 8x16, 256 glyphs.
|
||||
/* SchOS OS System Font - 8x16, 256 glyphs.
|
||||
*
|
||||
* The upper half is CP437, the IBM PC character set: 0x82 is 'e' with an
|
||||
* acute, 0xE9 is a capital theta, 0xB0-0xDF are shading and box-drawing.
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ struct input_event {
|
|||
// EVIOCGRAB -- take/release exclusive access to a device.
|
||||
//
|
||||
// Linux's _IOW('E', 0x90, int). Spelled as the resulting constant rather than
|
||||
// built from an _IOW macro because Schunix has no ioctl-encoding macros and
|
||||
// built from an _IOW macro because SchOS has no ioctl-encoding macros and
|
||||
// inventing a set just for this would be a bigger change than the feature.
|
||||
// A non-zero argument grabs, zero releases; the argument is passed by value.
|
||||
#define EVIOCGRAB 0x40044590
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
// GENERATED by tools/mklogo.py -- do not edit. Run `make logo`.
|
||||
// source: Assets/Schunix Small Logo.png
|
||||
// source: Assets/SchOS Small Logo.png
|
||||
//
|
||||
// An ink-coverage mask, not colour: 0 is background and full scale is
|
||||
// solid logo. Whoever draws it picks the colour, so the palette stays in
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// PCI bus enumeration and driver binding.
|
||||
//
|
||||
// Until this existed, every driver in Schunix found its hardware by knowing
|
||||
// Until this existed, every driver in SchOS found its hardware by knowing
|
||||
// where it was: IDE at 0x1F0 because IDE has always been at 0x1F0, the
|
||||
// framebuffer wherever the BIOS's VBE call said. That works for exactly the
|
||||
// devices that predate PCI and for nothing else. A NIC, an AHCI controller,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Schunix — POSIX-compatibility types used by kernel syscall handlers.
|
||||
// SchOS — POSIX-compatibility types used by kernel syscall handlers.
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
#include "date.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
// Schunix visual identity — one palette, shared by everything that draws.
|
||||
// SchOS visual identity — one palette, shared by everything that draws.
|
||||
//
|
||||
// This header exists because there were three unrelated designs and the seams
|
||||
// showed. The bootloader splash was deep purple with gold text, deliberately
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@
|
|||
// unrelated physical page at the next 4K boundary. Any multi-byte
|
||||
// access through it must stay within a single page.
|
||||
//
|
||||
// These helpers encapsulate both rules. Because Schunix (like old x86
|
||||
// These helpers encapsulate both rules. Because SchOS (like old x86
|
||||
// without SMAP) keeps the user page table active in kernel mode, a raw
|
||||
// user virtual address is directly dereferenceable once the whole range
|
||||
// has been validated — that is what user_ptr() hands back, and why the
|
||||
// result is safe across page boundaries where a uva2ka() pointer is not.
|
||||
#ifndef SCHUNIX_UACCESS_H
|
||||
#define SCHUNIX_UACCESS_H
|
||||
#ifndef SCHOS_UACCESS_H
|
||||
#define SCHOS_UACCESS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
|
@ -46,4 +46,4 @@ int copy_to_user(addr_t uaddr, const void *src, uint64 n);
|
|||
// or exceeds USER_STR_MAX.
|
||||
long strlen_user(addr_t uaddr);
|
||||
|
||||
#endif // SCHUNIX_UACCESS_H
|
||||
#endif // SCHOS_UACCESS_H
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// it is an assertion that exactly that much exists. Boot a machine with less
|
||||
// and kinit1() walks off the end of RAM into nothing; boot one with more and
|
||||
// every byte above 224 MB is invisible. Measured before this file existed:
|
||||
// Schunix booted at 224 MB and triple faulted at 192 MB, for no reason at all.
|
||||
// SchOS booted at 224 MB and triple faulted at 192 MB, for no reason at all.
|
||||
//
|
||||
// The firmware has known the answer the whole time. boot/stage2.S asks it with
|
||||
// INT 0x15 / E820 in real mode -- the same interface Linux's boot stub and GRUB
|
||||
|
|
@ -92,7 +92,7 @@ e820_init(void)
|
|||
// Below this the kernel image, its page tables and the DMA arena do not fit,
|
||||
// and continuing produces a failure much harder to read than this line.
|
||||
if (top < PHYSTOP_MIN) {
|
||||
cprintf("e820: only %d MB usable; Schunix needs at least %d MB\n",
|
||||
cprintf("e820: only %d MB usable; SchOS needs at least %d MB\n",
|
||||
(int)(top / (1024 * 1024)), (int)(PHYSTOP_MIN / (1024 * 1024)));
|
||||
// Left at the fallback deliberately rather than lowered: a machine this
|
||||
// small is going to fail, and it should fail having said why.
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ seginit(void)
|
|||
// and SS from +8, so the *slot* must exist to keep the
|
||||
// [UCODE32, UDATA, UCODE] triple consecutive. See syscallinit.
|
||||
// SEG_KCPU is a leftover slot number from 32-bit xv6, where %gs held the
|
||||
// per-CPU pointer. Schunix uses FS_BASE/TLS instead, but the
|
||||
// per-CPU pointer. SchOS uses FS_BASE/TLS instead, but the
|
||||
// index has to stay occupied or SEG_TSS stops landing at 7.
|
||||
//
|
||||
// Deleting either moves every descriptor after it and breaks sysret.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ static void mpmain(void) __attribute__((noreturn));
|
|||
extern char end[]; // first address after kernel loaded from ELF file
|
||||
|
||||
// Set by stage2main.c (boot/stage2main.c, BOOT_VERBOSE_FLAG_ADDR) when the
|
||||
// user picks "Boot Schunix (verbose)" from the F8 boot menu; read once here,
|
||||
// user picks "Boot SchOS (verbose)" from the F8 boot menu; read once here,
|
||||
// before anything else, so subsystem init can log its own steps.
|
||||
int boot_verbose;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// PSOGM — the Schunix crash screen.
|
||||
// PSOGM — the SchOS crash screen.
|
||||
//
|
||||
// The name is a nod to the Amiga's "Guru Meditation", but nothing else about
|
||||
// this is a nod to 1985. Three things it is built around:
|
||||
|
|
@ -439,7 +439,7 @@ paint(char *reason, addr_t *pcs, int npcs)
|
|||
|
||||
// Left-aligned, not centred. Centred text reads as a poster; this is a
|
||||
// report, and a report is read down the left edge.
|
||||
vga_text_at(left, y, "Schunix ran into a problem and needs to restart.",
|
||||
vga_text_at(left, y, "SchOS ran into a problem and needs to restart.",
|
||||
PSOGM_FG);
|
||||
y += ch + ch / 2;
|
||||
vga_text_at(left, y, "Nothing on your disks was touched by this.",
|
||||
|
|
@ -492,7 +492,7 @@ report_serial(char *reason, addr_t *pcs, int npcs)
|
|||
{
|
||||
cprintf("\n");
|
||||
cprintf(" :(\n\n");
|
||||
cprintf(" Schunix ran into a problem and needs to restart.\n");
|
||||
cprintf(" SchOS ran into a problem and needs to restart.\n");
|
||||
cprintf(" PSOGM -- Purple Screen of Guru Meditation\n\n");
|
||||
|
||||
for (int i = 0; i < nfields; i++) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// The kernel has always known how long it had been running -- `ticks`, bumped
|
||||
// 100 times a second by the timer interrupt -- and has never known what time it
|
||||
// was. sys_gettimeofday() returned `ticks / 100` as though it were seconds
|
||||
// since the epoch, so every Schunix machine believed it was the 1st of January
|
||||
// since the epoch, so every SchOS machine believed it was the 1st of January
|
||||
// 1970 and that the date advanced at the rate of its own uptime. `date` printed
|
||||
// a number that barely moved, which is what it looks like when a clock is
|
||||
// counting from the wrong place rather than not counting at all.
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ text_selftest(void)
|
|||
int line = f->ops->height(f) + 6;
|
||||
int y = 80;
|
||||
|
||||
text_draw(&s, f, 60, y + base, "Schunix text rendering", SCH_FG);
|
||||
text_draw(&s, f, 60, y + base, "SchOS text rendering", SCH_FG);
|
||||
y += line * 2;
|
||||
|
||||
// Deliberately not on a multiple of eight. On the old console this string
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ fb_ioctl(int request, addr_t arg)
|
|||
if (!f)
|
||||
return -EFAULT;
|
||||
memset(f, 0, sizeof(*f));
|
||||
safestrcpy(f->id, "schunixfb", sizeof(f->id));
|
||||
safestrcpy(f->id, "schosfb", sizeof(f->id));
|
||||
f->smem_start = (unsigned long)vga_fb_phys();
|
||||
f->smem_len = (unsigned int)vga_fb_size();
|
||||
f->type = FB_TYPE_PACKED_PIXELS;
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ gen_cpuinfo(struct sbuf *sb)
|
|||
// otherwise be told a VM with four processors has four to schedule on, when
|
||||
// three of them are enumerated and idle. "cpu cores" stays the present count,
|
||||
// which is what that field means.
|
||||
// Real values, from CPUID. These used to read "Schunix" and "Schunix virtual
|
||||
// Real values, from CPUID. These used to read "SchOS" and "SchOS virtual
|
||||
// CPU" -- a thing to print when you have not asked the processor, and
|
||||
// actively unhelpful, because identifying the machine is the one question
|
||||
// /proc/cpuinfo exists to answer.
|
||||
|
|
@ -204,7 +204,8 @@ gen_cpuinfo(struct sbuf *sb)
|
|||
static void
|
||||
gen_version(struct sbuf *sb)
|
||||
{
|
||||
sb_puts(sb, "Schunix version 0.1.0 (schunix) #1 SMP x86_64\n");
|
||||
// The kernel's name, not the system's -- same as "Linux version 6.x" here.
|
||||
sb_puts(sb, "SchIFT version 0.1.0 (schift) #1 SMP x86_64\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ load_outline(struct ttf *f, int gid, struct outline *o)
|
|||
// A negative contour count means a composite: the glyph is other glyphs
|
||||
// placed at offsets. This is not an exotic case to skip -- `i` is built from
|
||||
// a dotless i plus the dot, so skipping composites loses a letter from
|
||||
// "Schunix", which is exactly how the gap was found.
|
||||
// "SchOS", which is exactly how the gap was found.
|
||||
//
|
||||
// Only the translated case is handled: components with a scale or a 2x2
|
||||
// matrix are rare outside of synthesised obliques, and applying a transform
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ uartearlyinit(void)
|
|||
|
||||
|
||||
// Announce that we're here.
|
||||
for(p="Schunix UART...\n"; *p; p++)
|
||||
for(p="SchOS UART...\n"; *p; p++)
|
||||
uartputc(*p);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "errno.h"
|
||||
|
||||
// Binaries with entry points at 0x100000+ are musl/Linux-ABI.
|
||||
// Schunix-native binaries (init) are linked at 0x4000.
|
||||
// SchOS-native binaries (init) are linked at 0x4000.
|
||||
#define LINUX_ABI_ENTRY_THRESHOLD 0x100000UL
|
||||
extern int linux_syscall_map[];
|
||||
extern int linux_syscall_map_size;
|
||||
|
|
@ -158,7 +158,7 @@ exec(char *path, char **argv)
|
|||
}
|
||||
|
||||
// Auto-select syscall ABI: musl binaries have entry >= 0x100000;
|
||||
// Schunix-native binaries (init) are linked at 0x4000.
|
||||
// SchOS-native binaries (init) are linked at 0x4000.
|
||||
if (elf.entry >= LINUX_ABI_ENTRY_THRESHOLD) {
|
||||
myproc()->syscall_map = linux_syscall_map;
|
||||
myproc()->map_size = linux_syscall_map_size;
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ fileread(struct file *f, char *addr, int n)
|
|||
}
|
||||
|
||||
if((f->ip->rwmode & 2) == 0){
|
||||
cprintf("Schunix: permission denied (read)\n");
|
||||
cprintf("SchOS: permission denied (read)\n");
|
||||
iunlock(f->ip);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -208,7 +208,7 @@ filewrite(struct file *f, char *addr, int n)
|
|||
}
|
||||
|
||||
if((f->ip->rwmode & 1) == 0){
|
||||
cprintf("Schunix: permission denied (write)\n");
|
||||
cprintf("SchOS: permission denied (write)\n");
|
||||
iunlock(f->ip);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ static void sbputi(struct sb *s, int64 v)
|
|||
// Linux's /proc/<pid>/stat, as far as anything here reads it.
|
||||
//
|
||||
// The field order is not negotiable: ps counts fields by position, so a
|
||||
// missing one silently shifts everything after it. Fields Schunix does not
|
||||
// missing one silently shifts everything after it. Fields SchOS does not
|
||||
// track are zero, which is what Linux itself reports for things a given
|
||||
// process has never done.
|
||||
static char
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ schfs_kroot(void)
|
|||
/* Phase 2 has no VFS integration -- SchFS files are not reachable */
|
||||
/* through open(2) yet -- so this is how the mount is observable from */
|
||||
/* userland at all. It reports the volume and lists the root directory, */
|
||||
/* which is enough to confirm from inside a running Schunix that the */
|
||||
/* which is enough to confirm from inside a running SchOS that the */
|
||||
/* kernel really did parse an image mkschfs wrote. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Linux x86_64 syscall number -> Schunix syscall number translation.
|
||||
// Linux x86_64 syscall number -> SchOS syscall number translation.
|
||||
// Enabled per process by sys_enable_linux_abi (see kernel/sys/sys_compat.c).
|
||||
//
|
||||
// This file used to be the second half of a two-place registration scheme: a
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define LINUX_NSYSCALL NSYSCALLS
|
||||
|
||||
// Index: Linux x86_64 syscall number. Value: Schunix SYS_* number, or 0 for
|
||||
// Index: Linux x86_64 syscall number. Value: SchOS SYS_* number, or 0 for
|
||||
// "not implemented" (syscall() then returns -ENOSYS).
|
||||
//
|
||||
// Syscalls declared NO_LINUX in table.inc all land on the single scratch index
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@ sys_uname(void)
|
|||
struct utsname *u = (struct utsname*)user_ptr(ubuf, sizeof(*u));
|
||||
if (!u) return -EFAULT;
|
||||
memset(u, 0, sizeof(*u));
|
||||
memmove(u->sysname, "Schunix", 8);
|
||||
memmove(u->nodename, "schunix", 8);
|
||||
memmove(u->sysname, "SchIFT", 7);
|
||||
memmove(u->nodename, "schos", 6);
|
||||
memmove(u->release, "0.1.0", 6);
|
||||
memmove(u->version, "#1", 3);
|
||||
memmove(u->machine, "x86_64", 7);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// Linux-ABI-compatible struct stat (x86_64 "struct stat" from
|
||||
// musl 1.2.5 bits/stat.h) — musl/toybox/dash parse st_mode directly
|
||||
// out of this exact byte layout, which bears no resemblance to Schunix's
|
||||
// out of this exact byte layout, which bears no resemblance to SchOS's
|
||||
// own native `struct stat` (stat.h). Without this, every Linux-ABI process
|
||||
// reading stat() results (e.g. ls checking S_ISDIR to decide whether to
|
||||
// list a directory or just print its name) gets garbage.
|
||||
|
|
@ -825,7 +825,7 @@ sys_getdents64(void)
|
|||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Custom SchunixFS ops
|
||||
// Custom SchOSFS ops
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
addr_t sys_delete(void)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Segregated Kernel -- central syscall table. ONE line per syscall.
|
||||
//
|
||||
// Format: SYSCALL(nr, linux_nr, name)
|
||||
// nr Schunix native syscall number
|
||||
// nr SchOS native syscall number
|
||||
// linux_nr Linux x86_64 syscall number, or NO_LINUX if none
|
||||
// name implemented as sys_<name>() in kernel/sys/sys_*.c
|
||||
//
|
||||
|
|
@ -120,7 +120,7 @@ SYSCALL( 60, 16, ioctl)
|
|||
// translation answered "bad syscall" before the stub could answer ENOSYS.
|
||||
// Now that they do something they need the numbers programs actually use.
|
||||
//
|
||||
// `shutdown` is deliberately not the name here: Schunix already has a native
|
||||
// `shutdown` is deliberately not the name here: SchOS already has a native
|
||||
// shutdown() that powers the machine off (syscall 32), and two syscalls
|
||||
// cannot share a sys_ function name. Linux 48 maps to sockshutdown instead.
|
||||
SYSCALL( 40, 41, socket)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Schunix — first-party userland runtime: _start entry and exit.
|
||||
// SchOS — first-party userland runtime: _start entry and exit.
|
||||
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Schunix — process entry point.
|
||||
* SchOS — process entry point.
|
||||
*
|
||||
* This has to be assembly, and the reason is worth recording.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Schunix ports — third-party software, one directory per port.
|
||||
# SchOS ports — third-party software, one directory per port.
|
||||
# All ports are permissive-licensed (MIT, BSD, 0BSD, Apache 2.0).
|
||||
#
|
||||
# ports/musl/ libc — installs headers/libs to build/ports/musl/prefix
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
# Ports that live in this directory but are deliberately not built by `make`.
|
||||
# Empty for now; the filter stays because the reason it existed will recur --
|
||||
# a port whose licence cannot be combined with Apache-2.0 can be kept here for
|
||||
# local testing but must never be built into a Schunix image.
|
||||
# local testing but must never be built into a SchOS image.
|
||||
NOTPORTS :=
|
||||
PORTS := $(filter-out $(NOTPORTS), \
|
||||
$(patsubst %/,%,$(sort $(dir $(wildcard */Makefile)))))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Shared definitions for all Schunix ports.
|
||||
# Shared definitions for all SchOS ports.
|
||||
# Include this at the top of each port's Makefile: include ../mk/port.mk
|
||||
#
|
||||
# Layout contract — a port directory contains ONLY hand-written files:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# mksh (MirBSD Korn Shell) — permissive: https://www.mirbsd.org/mksh.htm
|
||||
# Installed as /bin/sh — Schunix standardizes on "sh" as the one shell name;
|
||||
# Installed as /bin/sh — SchOS standardizes on "sh" as the one shell name;
|
||||
# no ksh/dash/other aliases are installed or looked up by init.
|
||||
|
||||
include ../mk/port.mk
|
||||
|
|
@ -10,7 +10,7 @@ MKSH_URL := http://www.mirbsd.org/MirOS/dist/mir/mksh/mksh-$(MKSH_VERSION).t
|
|||
|
||||
TARBALL := $(DISTDIR)/mksh-$(MKSH_VERSION).tgz
|
||||
|
||||
CFLAGS := -static -D__SCHUNIX__ -I$(MUSL)/include -fno-stack-protector
|
||||
CFLAGS := -static -D__SCHOS__ -I$(MUSL)/include -fno-stack-protector
|
||||
LDFLAGS := -static -L$(MUSL)/lib -lc
|
||||
|
||||
$(TARBALL): | $(DISTDIR)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ $(SRCDIR): $(TARBALL)
|
|||
# so creating it bumps that directory's mtime — making the directory forever
|
||||
# newer than the stamp it contains, and re-running this rule on every single
|
||||
# build. The second run then fails, because the patch does not apply twice.
|
||||
$(SRCDIR)/.patched: patches/0001-schunix-tls.patch | $(SRCDIR)
|
||||
cd $(SRCDIR) && patch -p1 < $(CURDIR)/patches/0001-schunix-tls.patch
|
||||
$(SRCDIR)/.patched: patches/0001-schos-tls.patch | $(SRCDIR)
|
||||
cd $(SRCDIR) && patch -p1 < $(CURDIR)/patches/0001-schos-tls.patch
|
||||
touch $@
|
||||
|
||||
$(BUILDDIR)/config.mak: $(SRCDIR)/.patched
|
||||
|
|
@ -37,7 +37,7 @@ $(BUILDDIR)/config.mak: $(SRCDIR)/.patched
|
|||
--prefix=$(PREFIX) \
|
||||
--disable-shared \
|
||||
CC=$(CC) \
|
||||
CFLAGS="-D__SCHUNIX__ -fno-stack-protector"
|
||||
CFLAGS="-D__SCHOS__ -fno-stack-protector"
|
||||
|
||||
$(BUILDDIR)/lib/libc.a: $(BUILDDIR)/config.mak
|
||||
$(MAKE) -C $(BUILDDIR)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
From: Schunix Project <kernel@schunix.org>
|
||||
Subject: [PATCH] schunix: TLS via global, mallocng decls, optional malloc tracing
|
||||
From: SchOS Project <kernel@schos.org>
|
||||
Subject: [PATCH] schos: TLS via global, mallocng decls, optional malloc tracing
|
||||
|
||||
Three local changes to musl 1.2.5, kept in one patch because they are all
|
||||
"make musl work on Schunix" and share a lifetime.
|
||||
"make musl work on SchOS" and share a lifetime.
|
||||
|
||||
1. arch/x86_64/pthread_arch.h, src/env/__init_tls.c - TLS.
|
||||
Schunix's kernel saves/restores FS_BASE at the syscall boundary, so
|
||||
SchOS's kernel saves/restores FS_BASE at the syscall boundary, so
|
||||
arch_prctl(ARCH_SET_FS) is safe from userspace. __get_tp() is redirected
|
||||
through a global uintptr_t (__schunix_tp) set at the START of __init_tp(),
|
||||
through a global uintptr_t (__schos_tp) set at the START of __init_tp(),
|
||||
before __set_thread_area() is called. The rest of __init_tp() runs
|
||||
normally so td->locale and the other pthread fields still initialise.
|
||||
|
||||
|
|
@ -20,17 +20,17 @@ Three local changes to musl 1.2.5, kept in one patch because they are all
|
|||
|
||||
3. src/malloc/mallocng/meta.h, malloc.c - diagnostics, inert by default.
|
||||
get_meta()/alloc_group() tracing that dumps group/meta pointers to fd 2,
|
||||
entirely inside #ifdef SCHUNIX_MALLOC_DEBUG, which nothing defines. Kept
|
||||
entirely inside #ifdef SCHOS_MALLOC_DEBUG, which nothing defines. Kept
|
||||
because this is the instrumentation that resolved the boot-crash
|
||||
investigation in docs/architecture/kernel-history.md section 1; build
|
||||
with -DSCHUNIX_MALLOC_DEBUG to re-enable.
|
||||
with -DSCHOS_MALLOC_DEBUG to re-enable.
|
||||
|
||||
--- a/arch/x86_64/pthread_arch.h 2024-03-01 03:07:33.000000000 +0100
|
||||
+++ b/arch/x86_64/pthread_arch.h 2026-08-01 19:11:51.533102649 +0200
|
||||
@@ -1,8 +1,13 @@
|
||||
+#ifdef __SCHUNIX__
|
||||
+extern uintptr_t __schunix_tp;
|
||||
+static inline uintptr_t __get_tp() { return __schunix_tp; }
|
||||
+#ifdef __SCHOS__
|
||||
+extern uintptr_t __schos_tp;
|
||||
+static inline uintptr_t __get_tp() { return __schos_tp; }
|
||||
+#else
|
||||
static inline uintptr_t __get_tp()
|
||||
{
|
||||
|
|
@ -47,18 +47,18 @@ Three local changes to musl 1.2.5, kept in one patch because they are all
|
|||
|
||||
volatile int __thread_list_lock;
|
||||
|
||||
+#ifdef __SCHUNIX__
|
||||
+uintptr_t __schunix_tp;
|
||||
+#ifdef __SCHOS__
|
||||
+uintptr_t __schos_tp;
|
||||
+#endif
|
||||
+
|
||||
int __init_tp(void *p)
|
||||
{
|
||||
pthread_t td = p;
|
||||
td->self = td;
|
||||
+ // Set __schunix_tp for __get_tp() before calling __set_thread_area.
|
||||
+ // Set __schos_tp for __get_tp() before calling __set_thread_area.
|
||||
+ // The kernel now correctly saves/restores FS_BASE at the syscall boundary.
|
||||
+#ifdef __SCHUNIX__
|
||||
+ __schunix_tp = (uintptr_t)TP_ADJ(p);
|
||||
+#ifdef __SCHOS__
|
||||
+ __schos_tp = (uintptr_t)TP_ADJ(p);
|
||||
+#endif
|
||||
int r = __set_thread_area(TP_ADJ(p));
|
||||
if (r < 0) return -1;
|
||||
|
|
@ -82,20 +82,20 @@ Three local changes to musl 1.2.5, kept in one patch because they are all
|
|||
#include <limits.h>
|
||||
#include "glue.h"
|
||||
|
||||
+#ifdef SCHUNIX_MALLOC_DEBUG
|
||||
+static void schunix_hex(char *out, uint64_t v) {
|
||||
+#ifdef SCHOS_MALLOC_DEBUG
|
||||
+static void schos_hex(char *out, uint64_t v) {
|
||||
+ static const char digits[] = "0123456789abcdef";
|
||||
+ for (int i = 15; i >= 0; i--) { out[i] = digits[v & 0xf]; v >>= 4; }
|
||||
+}
|
||||
+static void schunix_dbg(const char *tag, uint64_t a, uint64_t b, uint64_t c) {
|
||||
+static void schos_dbg(const char *tag, uint64_t a, uint64_t b, uint64_t c) {
|
||||
+ char buf[128];
|
||||
+ int n = 0;
|
||||
+ buf[n++]='['; buf[n++]='D'; buf[n++]='B'; buf[n++]='G'; buf[n++]=']'; buf[n++]=' ';
|
||||
+ for (const char *p = tag; *p; p++) buf[n++] = *p;
|
||||
+ buf[n++]=' ';
|
||||
+ schunix_hex(buf+n, a); n += 16; buf[n++]=' ';
|
||||
+ schunix_hex(buf+n, b); n += 16; buf[n++]=' ';
|
||||
+ schunix_hex(buf+n, c); n += 16; buf[n++]='\n';
|
||||
+ schos_hex(buf+n, a); n += 16; buf[n++]=' ';
|
||||
+ schos_hex(buf+n, b); n += 16; buf[n++]=' ';
|
||||
+ schos_hex(buf+n, c); n += 16; buf[n++]='\n';
|
||||
+ __syscall(SYS_write, 2, buf, n);
|
||||
+}
|
||||
+#endif
|
||||
|
|
@ -107,13 +107,13 @@ Three local changes to musl 1.2.5, kept in one patch because they are all
|
|||
}
|
||||
const struct group *base = (const void *)(p - UNIT*offset - UNIT);
|
||||
const struct meta *meta = base->meta;
|
||||
+#ifdef SCHUNIX_MALLOC_DEBUG
|
||||
+ schunix_dbg("get_meta p", (uint64_t)p, (uint64_t)offset, (uint64_t)index);
|
||||
+#ifdef SCHOS_MALLOC_DEBUG
|
||||
+ schos_dbg("get_meta p", (uint64_t)p, (uint64_t)offset, (uint64_t)index);
|
||||
+ {
|
||||
+ volatile uint64_t *rawbase = (volatile uint64_t *)base;
|
||||
+ schunix_dbg("get_meta RAW reread base[0..2]", rawbase[0], rawbase[1], rawbase[2]);
|
||||
+ schos_dbg("get_meta RAW reread base[0..2]", rawbase[0], rawbase[1], rawbase[2]);
|
||||
+ }
|
||||
+ schunix_dbg("get_meta base/meta/meta->mem", (uint64_t)base, (uint64_t)meta, (uint64_t)meta->mem);
|
||||
+ schos_dbg("get_meta base/meta/meta->mem", (uint64_t)base, (uint64_t)meta, (uint64_t)meta->mem);
|
||||
+#endif
|
||||
assert(meta->mem == base);
|
||||
assert(index <= meta->last_idx);
|
||||
|
|
@ -124,9 +124,9 @@ Three local changes to musl 1.2.5, kept in one patch because they are all
|
|||
m->last_idx = cnt-1;
|
||||
m->freeable = 1;
|
||||
m->sizeclass = sc;
|
||||
+#ifdef SCHUNIX_MALLOC_DEBUG
|
||||
+ schunix_dbg("alloc_group p/m/cnt", (uint64_t)p, (uint64_t)m, (uint64_t)cnt);
|
||||
+ schunix_dbg("alloc_group readback mem->meta", (uint64_t)m->mem, (uint64_t)m->mem->meta, (uint64_t)sc);
|
||||
+#ifdef SCHOS_MALLOC_DEBUG
|
||||
+ schos_dbg("alloc_group p/m/cnt", (uint64_t)p, (uint64_t)m, (uint64_t)cnt);
|
||||
+ schos_dbg("alloc_group readback mem->meta", (uint64_t)m->mem, (uint64_t)m->mem->meta, (uint64_t)sc);
|
||||
+#endif
|
||||
return m;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# toybox — 0BSD-licensed: https://landley.net/toybox/
|
||||
# Provides Schunix's core utilities (ls, cat, cp, mv, rm, mkdir, ...) as a
|
||||
# Provides SchOS's core utilities (ls, cat, cp, mv, rm, mkdir, ...) as a
|
||||
# single multicall binary, installed under sysroot/bin/ once per applet name.
|
||||
#
|
||||
# mkfs (tools/mkfs.c) doesn't understand symlinks or hardlink dedup — each
|
||||
|
|
@ -16,7 +16,7 @@ TOYBOX_SHA256 := ad88a921133ae2231d9f2df875ec0bd42af4429145caea7d7db9e02208a6fd
|
|||
|
||||
TARBALL := $(DISTDIR)/toybox-$(TOYBOX_VERSION).tar.gz
|
||||
|
||||
CFLAGS := -static -D__SCHUNIX__ -I$(MUSL)/include -fno-stack-protector
|
||||
CFLAGS := -static -D__SCHOS__ -I$(MUSL)/include -fno-stack-protector
|
||||
LDFLAGS := -static -L$(MUSL)/lib -lc
|
||||
|
||||
# The applet list is not hard-coded any more: `toybox` with no arguments prints
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# projects/
|
||||
|
||||
Things that run **on** Schunix rather than things that **are** Schunix.
|
||||
Things that run **on** SchOS rather than things that **are** SchOS.
|
||||
|
||||
Everything above this directory — `kernel/`, `boot/`, `lib/`, `cmd/`,
|
||||
`include/` — is the operating system: it boots, it owns the hardware, and it
|
||||
|
|
@ -11,7 +11,7 @@ The split exists because the alternative gets bad quickly. A compositor,
|
|||
a window manager and a desktop are each larger than the kernel will be for a
|
||||
long time. Grown inside the OS tree they would blur into it: a compositor
|
||||
would start reaching into kernel headers because they are right there, the
|
||||
build would grow a dependency from the kernel to a GUI, and "does Schunix
|
||||
build would grow a dependency from the kernel to a GUI, and "does SchOS
|
||||
boot" would stop having a clear answer. Keeping them separate forces the
|
||||
boundary to be a real interface — syscalls and protocols — rather than a
|
||||
shared header nobody meant to share.
|
||||
|
|
@ -27,13 +27,13 @@ Concretely, code in here:
|
|||
|
||||
| Directory | What it is |
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `schcom/` | Schunix Compositor. Owns the display, composites clients, routes input. |
|
||||
| `schwm/` | Schunix Window Manager. Window placement, decoration, focus, on top of Schcom. |
|
||||
| `schde/` | Schunix Desktop Environment. Panel, launcher, settings, file manager. |
|
||||
| `schcom/` | SchOS Compositor. Owns the display, composites clients, routes input. |
|
||||
| `schwm/` | SchOS Window Manager. Window placement, decoration, focus, on top of Schcom. |
|
||||
| `schde/` | SchOS Desktop Environment. Panel, launcher, settings, file manager. |
|
||||
| `schinst/` | The installer, the installation environment, and `.sip` tooling. |
|
||||
| `schfs-linux/` | SchFS as a filesystem for Linux. FUSE first, a kernel module later. |
|
||||
|
||||
**`schfs-linux/` is written to stand on its own.** It does not mention Schunix
|
||||
**`schfs-linux/` is written to stand on its own.** It does not mention SchOS
|
||||
anywhere, and that is deliberate rather than an oversight: it is intended to be
|
||||
the first piece released, and it has to make sense to somebody who has never
|
||||
heard of the OS it came from — a filesystem is judged as a filesystem. The
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Schcom — the Schunix Compositor
|
||||
# Schcom — the SchOS Compositor
|
||||
|
||||
Owns the display. Every pixel that reaches the screen goes through it.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# SchDE — the Schunix Desktop Environment
|
||||
# SchDE — the SchOS Desktop Environment
|
||||
|
||||
The parts you actually look at: a panel, a launcher, settings, a file
|
||||
manager, a terminal.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# schinst — the installer, the installation environment, and `.sip`
|
||||
|
||||
Getting Schunix from an ISO onto a disk.
|
||||
Getting SchOS from an ISO onto a disk.
|
||||
|
||||
Three separate things live here:
|
||||
|
||||
1. **The installation environment.** A Schunix that boots from the ISO into a
|
||||
1. **The installation environment.** A SchOS that boots from the ISO into a
|
||||
known state with the installer running instead of a login shell. The ISO
|
||||
already boots to userspace without a hard disk (`make iso`), so this is a
|
||||
different init and a different root, not a different kernel.
|
||||
|
|
@ -17,7 +17,7 @@ Three separate things live here:
|
|||
|
||||
Not started. `.sip` needs its format written down before any code exists.
|
||||
|
||||
## `.sip` — Schunix Installation Package
|
||||
## `.sip` — SchOS Installation Package
|
||||
|
||||
The stated model is WIM, the image format Windows PE installs from, and the
|
||||
thing worth copying from WIM is that it is **file-based, not block-based**.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# SchWM — the Schunix Window Manager
|
||||
# SchWM — the SchOS Window Manager
|
||||
|
||||
Policy. Where windows go, which one has focus, what happens when you drag a
|
||||
title bar, how alt-tab behaves, what a window looks like at its edges.
|
||||
|
|
|
|||
6
run.ps1
|
|
@ -1,4 +1,4 @@
|
|||
# Schunix launcher (Windows side).
|
||||
# SchOS launcher (Windows side).
|
||||
#
|
||||
# Why this exists: without it you have to hand-type a QEMU command line, and a
|
||||
# hand-typed one drifts -- notably onto a stale fs.img, which boots to
|
||||
|
|
@ -35,7 +35,7 @@ $root = $PSScriptRoot
|
|||
|
||||
# The two images QEMU needs. These paths are the single source of truth --
|
||||
# keep them in sync with the 'qemu' and 'qemu-schfs' targets in the Makefile.
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' }
|
||||
else { Join-Path $root 'build\fs.img' }
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ if (-not $NoBuild) {
|
|||
# of memory, which leaves device 1 free for the SchFS volume. Booting the
|
||||
# normal kernel with a SchFS disk as hdb would leave it with no root.
|
||||
$target = if ($SchFS) { 'make ramroot && make build/schfs.img' } else { 'make' }
|
||||
& $bash -lc "cd /d/DEV/Schunix && $target"
|
||||
& $bash -lc "cd /d/DEV/SchOS && $target"
|
||||
if ($LASTEXITCODE -ne 0) { throw "build failed (exit $LASTEXITCODE)" }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Headless boot check: run Schunix under QEMU, type commands at the shell, and
|
||||
# Headless boot check: run SchOS under QEMU, type commands at the shell, and
|
||||
# assert on what actually comes back.
|
||||
#
|
||||
# Booting to a prompt proves nothing on its own -- a filesystem can mount and
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
param(
|
||||
[switch]$Fb,
|
||||
# Boot schunix.iso from an emulated optical drive with NO hard disk
|
||||
# Boot schos.iso from an emulated optical drive with NO hard disk
|
||||
# attached, which is the only way to prove the ISO is self-contained.
|
||||
# Needs `make iso` first.
|
||||
[switch]$Iso,
|
||||
|
|
@ -54,7 +54,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
# The root filesystem. SchFS is the only root there is, so this is not a
|
||||
# choice -- a kernel handed anything else on device 1 panics in forkret().
|
||||
$hdb = Join-Path $root 'build\schfs.img'
|
||||
|
|
@ -67,7 +67,7 @@ Remove-Item -Force $log -ErrorAction SilentlyContinue
|
|||
# on its own, and every one of these has broken at some point while the boot
|
||||
# still looked perfectly healthy.
|
||||
$commands = @(
|
||||
'echo hello-from-schunix > /tmp/bc.txt'
|
||||
'echo hello-from-schos > /tmp/bc.txt'
|
||||
'cat /tmp/bc.txt'
|
||||
'echo second-line >> /tmp/bc.txt'
|
||||
'wc -c /tmp/bc.txt'
|
||||
|
|
@ -161,7 +161,7 @@ $commands += 'echo MARKER-DONE'
|
|||
# The ISO run attaches no hard disk at all. That is the whole point: a kernel
|
||||
# that still quietly needs one would boot happily here otherwise, and only
|
||||
# fail on someone else's machine.
|
||||
$isoPath = Join-Path $root 'schunix.iso'
|
||||
$isoPath = Join-Path $root 'schos.iso'
|
||||
if ($Iso -and -not (Test-Path $isoPath)) { throw "no $isoPath -- run 'make iso' first" }
|
||||
|
||||
$drives = if ($Iso) {
|
||||
|
|
@ -222,7 +222,7 @@ $psi.Arguments = ($drives + $usbDevices + $monitor + @(
|
|||
$psi.RedirectStandardInput = $true
|
||||
$psi.UseShellExecute = $false
|
||||
|
||||
$what = if ($Iso) { 'schunix.iso, no hard disk' } else { "hdb = $(Split-Path $hdb -Leaf)" }
|
||||
$what = if ($Iso) { 'schos.iso, no hard disk' } else { "hdb = $(Split-Path $hdb -Leaf)" }
|
||||
Write-Host "==> booting ($what)" -ForegroundColor Cyan
|
||||
$p = [System.Diagnostics.Process]::Start($psi)
|
||||
|
||||
|
|
@ -372,12 +372,16 @@ function Expect($pattern, $what) {
|
|||
}
|
||||
|
||||
Expect 'MARKER-DONE' 'shell stayed alive through every command'
|
||||
Expect 'hello-from-schunix' 'a file written on the root filesystem reads back'
|
||||
Expect 'hello-from-schos' 'a file written on the root filesystem reads back'
|
||||
Expect 'second-line' 'appending to that file works'
|
||||
# 19 bytes of "hello-from-schunix\n" plus 12 of "second-line\n". The exact
|
||||
# 17 bytes of "hello-from-schos\n" plus 12 of "second-line\n". The exact
|
||||
# number is the point: an append that silently truncated still produced a file,
|
||||
# and only the byte count said which one.
|
||||
Expect '(?m)^\s*31\s' 'append extended the file rather than replacing it'
|
||||
#
|
||||
# It follows the string above, so changing that changes this -- the SchOS
|
||||
# rename shortened "hello-from-schunix" by two characters and this check went
|
||||
# red on a filesystem that was working perfectly.
|
||||
Expect '(?m)^\s*29\s' 'append extended the file rather than replacing it'
|
||||
Expect '(?m)^copy\.txt' 'a copied file appears in a new directory'
|
||||
Expect '(?ms)copy\.txt.*rmdir' 'rmdir removed the directory without an error'
|
||||
|
||||
|
|
@ -393,7 +397,7 @@ Expect 'vga: display controller' 'the display driver found its aperture'
|
|||
|
||||
Expect 'schfs: mounted' 'the kernel mounted SchFS as the root filesystem'
|
||||
Expect 'init: ready' 'init came up on a SchFS root'
|
||||
Expect 'label:\s*schunix' '/proc/schfs reports the volume label'
|
||||
Expect 'label:\s*schos' '/proc/schfs reports the volume label'
|
||||
Expect 'root_objectid:\s*16' '/proc/schfs reports the root object id'
|
||||
Expect 'dir\s+bin' 'the root directory really contains bin/'
|
||||
# / is the mounted volume, so mounting that same device again must be
|
||||
|
|
@ -415,7 +419,7 @@ if ($gens.Count -ge 2 -and
|
|||
}
|
||||
|
||||
if ($Fb) {
|
||||
Expect 'id\s+schunixfb' 'FBIOGET_FSCREENINFO identifies the device'
|
||||
Expect 'id\s+schosfb' 'FBIOGET_FSCREENINFO identifies the device'
|
||||
# 800x600 is what boot/stage2.S asks VBE for. Asserting the numbers rather
|
||||
# than just "the ioctl returned" is the point: the old code path returned
|
||||
# success with an untouched buffer, i.e. a 0x0 screen.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Boot Schunix, crash it on purpose, and capture the crash screen as an image.
|
||||
# Boot SchOS, crash it on purpose, and capture the crash screen as an image.
|
||||
#
|
||||
# The crash screen is the one part of the system you cannot look at by using
|
||||
# the system, so it is the one part that quietly rots. This drives it through
|
||||
|
|
@ -21,7 +21,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
|
||||
$log = Join-Path $root 'build\crashshot.log'
|
||||
$ppm = Join-Path $root $Out
|
||||
|
|
@ -96,7 +96,7 @@ if (Test-Path $log) {
|
|||
$text = Get-Content $log -Raw
|
||||
Write-Host "==> serial transcript" -ForegroundColor Cyan
|
||||
# Only the crash report, not the whole boot.
|
||||
$idx = $text.IndexOf('Schunix stopped')
|
||||
$idx = $text.IndexOf('SchOS stopped')
|
||||
if ($idx -ge 0) { Write-Host $text.Substring($idx) } else { Write-Host $text }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Boot Schunix, run the display self-test, and capture the result as an image.
|
||||
# Boot SchOS, run the display self-test, and capture the result as an image.
|
||||
#
|
||||
# The display class cannot be checked without a display: the assertion is "did
|
||||
# the right pixels reach the screen", and the only instrument for that is a
|
||||
|
|
@ -26,7 +26,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
|
||||
$log = Join-Path $root 'build\crashshot.log'
|
||||
$ppm = Join-Path $root $Out
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = Join-Path $root 'build\fs.img'
|
||||
$log = Join-Path $root 'build\fbshot.log'
|
||||
$ppm = Join-Path $root "build\fb-$Mode.ppm"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# How much of Schunix is actually Schunix.
|
||||
# How much of SchOS is actually SchOS.
|
||||
#
|
||||
# `wc -l` over the whole tree answers a question nobody asked: it counts musl,
|
||||
# toybox, mksh and a NetBSD checkout, which between them are
|
||||
|
|
@ -136,13 +136,13 @@ $fmt = @(
|
|||
)
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ' Schunix — first-party source' -ForegroundColor Cyan
|
||||
Write-Host ' SchOS — first-party source' -ForegroundColor Cyan
|
||||
Write-Host ''
|
||||
Write-Host (($results | Where-Object { $_.Files -gt 0 } | Sort-Object Lines -Descending | Format-Table $fmt -AutoSize | Out-String))
|
||||
|
||||
# Two totals, because they answer different questions and conflating them
|
||||
# flatters the number. "The OS" is what boots and runs on the machine; docs,
|
||||
# host-side tools and the projects/ stubs are first-party but are not Schunix
|
||||
# host-side tools and the projects/ stubs are first-party but are not SchOS
|
||||
# running on hardware. Linux 0.01's 10,239 lines were kernel, headers and boot
|
||||
# -- no documentation and no build tooling -- so only the first total is a fair
|
||||
# comparison.
|
||||
|
|
@ -182,7 +182,7 @@ Write-Host ''
|
|||
# measure -- every line of every file in the tarball, comments included.
|
||||
$lin = 10239
|
||||
Write-Host (' For scale: Linux 0.01 was {0:N0} lines (kernel, headers, boot -- the' -f $lin) -ForegroundColor DarkGray
|
||||
Write-Host (' same things counted above as THE OS ITSELF). Schunix is {0:N1}x that.' -f ($osT / $lin)) -ForegroundColor DarkGray
|
||||
Write-Host (' same things counted above as THE OS ITSELF). SchOS is {0:N1}x that.' -f ($osT / $lin)) -ForegroundColor DarkGray
|
||||
Write-Host ''
|
||||
|
||||
if ($PerFile) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Build a bootable Schunix ISO, ready for VMware or a real machine.
|
||||
# Build a bootable SchOS ISO, ready for VMware or a real machine.
|
||||
#
|
||||
# Wraps `make iso`, which builds the ramdisk-root variant and wraps it in an
|
||||
# El Torito image. The ramdisk root is the point: the ISO carries a complete
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
# tools\makeiso.ps1 -Run build it, then boot it under QEMU to check
|
||||
# tools\makeiso.ps1 -Clean force a full rebuild first
|
||||
#
|
||||
# Afterwards the ISO is schunix.iso in the repository root; point a VM's optical
|
||||
# Afterwards the ISO is schos.iso in the repository root; point a VM's optical
|
||||
# drive at it and boot from CD.
|
||||
|
||||
param(
|
||||
|
|
@ -88,8 +88,8 @@ if ($code -ne 0) {
|
|||
Fail "make iso returned $code"
|
||||
}
|
||||
|
||||
$iso = Join-Path $root 'schunix.iso'
|
||||
if (-not (Test-Path $iso)) { Fail "schunix.iso was not produced" }
|
||||
$iso = Join-Path $root 'schos.iso'
|
||||
if (-not (Test-Path $iso)) { Fail "schos.iso was not produced" }
|
||||
|
||||
# `make iso` leaves the tree holding objects compiled with -DRAMDISK_ROOT. A
|
||||
# following plain `make` would then fail to link, on a missing ramdisk symbol,
|
||||
|
|
@ -106,7 +106,7 @@ Write-Host " New VM -> I will install the OS later -> Other / Other 64-bit"
|
|||
Write-Host " CD/DVD -> Use ISO image file -> $iso, and tick Connect at power on"
|
||||
Write-Host " Boot order: CD-ROM first (F2 at power on for the firmware setup)"
|
||||
Write-Host ""
|
||||
Write-Host " Set the VM to BIOS, not UEFI. Schunix's loader is 16-bit real"
|
||||
Write-Host " Set the VM to BIOS, not UEFI. SchOS's loader is 16-bit real"
|
||||
Write-Host " mode and there is no EFI stub yet, so a UEFI-only VM will not boot."
|
||||
Write-Host ""
|
||||
Write-Host " Processors: as many as you like. SMP works as of 2026-08-08;"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
#!/bin/sh
|
||||
# Build a bootable Schunix ISO.
|
||||
# Build a bootable SchOS ISO.
|
||||
#
|
||||
# tools/mkiso.sh [output.iso]
|
||||
#
|
||||
# The disc boots through El Torito's "no emulation" mode, which is the only
|
||||
# one of the three that fits how Schunix actually loads itself.
|
||||
# one of the three that fits how SchOS actually loads itself.
|
||||
#
|
||||
# floppy emulation caps the image at 2.88 MB; the ramdisk-root kernel
|
||||
# alone is bigger than that.
|
||||
# hard disk emulation presents the image through the BIOS's INT 13h, and
|
||||
# Schunix's loader does not use INT 13h -- it drives
|
||||
# SchOS's loader does not use INT 13h -- it drives
|
||||
# the IDE controller's registers directly, which
|
||||
# cannot reach a BIOS-emulated drive.
|
||||
# no emulation the BIOS loads a chosen run of sectors at 0x7C00
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
#
|
||||
# STAGE2_SECTORS comes from the environment, set by the Makefile, because this
|
||||
# same number also lives in boot/bootasm.S, boot/stage2main.c and the dd offsets
|
||||
# in schunix.img's recipe. It was previously written out by hand in three
|
||||
# in schos.img's recipe. It was previously written out by hand in three
|
||||
# separate spots in this file alone, and raising it for the boot logo is what
|
||||
# turned that from a latent hazard into a broken image.
|
||||
#
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
set -e
|
||||
|
||||
BUILD=${BUILD:-build}
|
||||
OUT=${1:-schunix.iso}
|
||||
OUT=${1:-schos.iso}
|
||||
STAGE2_SECTORS=${STAGE2_SECTORS:-48}
|
||||
STAGE2_BYTES=$((STAGE2_SECTORS * 512))
|
||||
LOAD_SIZE=$((1 + STAGE2_SECTORS))
|
||||
|
|
@ -59,7 +59,7 @@ stage2_sz=$(wc -c < "$STAGE2")
|
|||
rm -rf "$STAGING"
|
||||
mkdir -p "$STAGING/boot"
|
||||
|
||||
cat "$CDBOOT" "$STAGE2" "$KERNEL" > "$STAGING/boot/schunix.bin"
|
||||
cat "$CDBOOT" "$STAGE2" "$KERNEL" > "$STAGING/boot/schos.bin"
|
||||
|
||||
# xorriso if it is here, mkisofs otherwise. Both accept the El Torito flags
|
||||
# below unchanged -- xorriso's -as mkisofs mode exists precisely to be
|
||||
|
|
@ -79,9 +79,9 @@ fi
|
|||
|
||||
$MKISOFS \
|
||||
-quiet \
|
||||
-V SCHUNIX \
|
||||
-A "Schunix" \
|
||||
-b boot/schunix.bin \
|
||||
-V SCHOS \
|
||||
-A "SchOS" \
|
||||
-b boot/schos.bin \
|
||||
-no-emul-boot \
|
||||
-boot-load-size "$LOAD_SIZE" \
|
||||
-o "$OUT" \
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ is ink -- which lets the kernel composite it in whatever the theme's accent
|
|||
happens to be, anti-aliased, at one byte per pixel. Storing RGB would be four
|
||||
times the size and would hardcode a colour into the kernel image.
|
||||
|
||||
python3 tools/mklogo.py "Assets/Schunix Small Logo.png" include/logo.h 128
|
||||
python3 tools/mklogo.py "Assets/SchOS Small Logo.png" include/logo.h 128
|
||||
"""
|
||||
|
||||
import sys, zlib, struct
|
||||
|
|
|
|||
|
|
@ -547,7 +547,7 @@ add_tree(uint64_t dirino, const char *hostdir)
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *out = NULL, *sysroot = NULL, *label = "schunix";
|
||||
const char *out = NULL, *sysroot = NULL, *label = "schos";
|
||||
uint64_t nblocks = 6000;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
# say -- would otherwise look exactly like a passing mutation test, which is
|
||||
# the same failure this script exists to catch.
|
||||
set -e
|
||||
cd /mnt/d/DEV/Schunix
|
||||
cd /mnt/d/DEV/SchOS
|
||||
|
||||
OBJ=kernel/fs/schfs/obj.c
|
||||
OBJW=kernel/fs/schfs/objw.c
|
||||
|
|
|
|||
|
|
@ -126,10 +126,10 @@ alpha = lambda n: "".join(chr(65 + i % 26) for i in range(n))
|
|||
|
||||
CASES = [
|
||||
"HELLO",
|
||||
"SCHUNIX",
|
||||
"SCHOS",
|
||||
"a",
|
||||
"0123456789",
|
||||
"SCHUNIX PANIC\ntrap 14 err 4 cpu 0\nrip ffffffff80104e2a",
|
||||
"SCHOS PANIC\ntrap 14 err 4 cpu 0\nrip ffffffff80104e2a",
|
||||
bytes(range(1, 40)).decode("latin-1"), # non-printable payload
|
||||
]
|
||||
# One payload that exactly fills each version, and one just under, so both the
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ main(int argc, char **argv)
|
|||
|
||||
const char *out = argc > 1 ? argv[1] : "build/qr.png";
|
||||
const char *text = argc > 2 ? argv[2] :
|
||||
"SCHUNIX PANIC\n"
|
||||
"SCHOS PANIC\n"
|
||||
"build 8f2a91c4\n"
|
||||
"trap 14 err 4 cpu 0\n"
|
||||
"rip ffffffff80104e2a\n"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue
|
|||
New-Item -ItemType Directory -Force $dir | Out-Null
|
||||
Remove-Item -Force $log -ErrorAction SilentlyContinue
|
||||
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = Join-Path $root 'build\fs.img'
|
||||
|
||||
$monPort = 55556 # not crashshot's port, so the two can run back to back
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Boot Schunix, run the text-rendering self-test, and capture the result as an image.
|
||||
# Boot SchOS, run the text-rendering self-test, and capture the result as an image.
|
||||
#
|
||||
# The display class cannot be checked without a display: the assertion is "did
|
||||
# the right pixels reach the screen", and the only instrument for that is a
|
||||
|
|
@ -26,7 +26,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
|
||||
$log = Join-Path $root 'build\crashshot.log'
|
||||
$ppm = Join-Path $root $Out
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ param(
|
|||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$root = Split-Path $PSScriptRoot -Parent
|
||||
$hda = Join-Path $root 'schunix.img'
|
||||
$hda = Join-Path $root 'schos.img'
|
||||
$hdb = Join-Path $root 'build\fs.img'
|
||||
$log = Join-Path $root 'build\ttyshot.log'
|
||||
$ppm = Join-Path $root $Out
|
||||
|
|
|
|||