| Filename | Latest commit message | Latest commit date |
|---|---|---|
fastfetch reported "getifaddrs(&ifAddrStruct) failed", and the right answer to
that is not a patch to fastfetch. Asking what interfaces a machine has is
something every networked program does, and on Linux there is exactly one way:
a NETLINK_ROUTE socket. musl implements getifaddrs() over it, so a libc call
that looks like a syscall is really a small protocol conversation -- and without
this side of it every caller fails the same way.
kernel/net/netlink.c is a responder rather than a general socket family. No
event stream, no multicast groups, nothing subscribes to link state: a request
arrives, the whole answer is generated into the socket's buffer, and reads drain
it. That shape is chosen, not a shortcut -- getifaddrs sends a dump and reads
until NLMSG_DONE with MSG_DONTWAIT, so generating at send time means a read
never blocks and the non-blocking flag is honoured for free.
RTM_GETLINK returns one RTM_NEWLINK per interface with IFLA_IFNAME and
IFLA_ADDRESS; RTM_GETADDR returns one RTM_NEWADDR per address with IFA_ADDRESS,
IFA_LOCAL and IFA_LABEL. Anything else gets a bare NLMSG_DONE, because the
caller's next move is a read either way and an unexpected error message is worse
than nothing to read.
The data is not netlink's. Interfaces come from the netdev class and addresses
from lwIP's netifs, exactly as /proc/netif reads them; nothing in the file knows
what an e1000 is. Interface indices matter more than they look -- getifaddrs
matches address records to link records by index, so the two dumps have to
agree. Loopback is 1, netdevs follow from 2.
Verified by reading it back through musl rather than by inspecting the bytes:
lo flags=0x49 fam=-1
eth0 flags=0x1043 fam=17 (AF_PACKET, the MAC)
lo flags=0x49 fam=2 addr=127.0.0.1 mask=255.0.0.0
eth0 flags=0x1043 fam=2 addr=10.0.2.15 mask=255.255.255.0
Correct flags, addresses and netmasks, and the link records pair with the
address records.
One thing this does not close: fastfetch's Local IP module defaults to
default-route-only, which calls ffNetifGetDefaultRouteIfName() and reads
/proc/net/route. SchOS has no routing table and no such file, so the module
still shows nothing -- now for a reason that is about routing rather than about
enumeration. That is the next file to provide.
socktest still passes; the AF_UNIX and AF_INET paths are untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
|
||
| .. | ||
| guru.svg | ||
| README.md | ||
| shift-mask.png | ||
| shift-mask.svg | ||
| shift.png | ||
| shift.svg | ||
| superseded-full-logo.png | ||
| superseded-text-logo.png | ||
| uberblock.svg | ||
Branding
Three marks, three different jobs. They are not interchangeable and the difference is not stylistic.
| Shift | the logo | An abstract mark. Non-human, non-animal. Signs the system. |
| Guru | the icon | A pictogram. Denotes one state. Has a face; has no body. |
| SchCotie | the mascot | A character. Has a body, poses and expressions. |
The distinction that decides everything else: a mascot has to be able to do things. An icon works once, at one size, in one state. A character has to work confused, pleased, asleep and from behind — which is why it costs more and why it is drawn last.
The one constraint everything answers to
The kernel draws its mark as a 128×128 single-channel coverage mask.
include/logo.h holds no colour at all — two pixels per byte, sixteen levels of
ink — and the kernel composites it in whatever include/theme.h says.
So any mark that will end up there has to survive as a solid shape in one colour at 128 px, and be recognisable at 24. That rules out hairlines, thin rings and anything that depends on a gradient to read. The mark this replaced failed on all three counts.
Colour is therefore the last decision, never the first. Design the silhouette, then colour it.
Shift — the logo
shift.svg
Three slabs, displaced: the layer diagram in ../architecture/README.md as a solid object, and the kernel's name (SchIFT) as a shape.
- Any colour. This is a fact about the pipeline, not a preference — the coverage mask carries none, so the loader draws it in metal and the kernel in the theme accent, from the same bytes.
- With or without a wordmark. Set "SchOS" beside it in Roboto Bold,
which is already in the tree (
ports/Roboto), already Apache-2.0, and already inNOTICE. - Non-human and non-animal, permanently. The character work belongs to SchCotie; a logo that starts growing a face has taken the mascot's job.
Guru — the icon
guru.svg
The crash face. Mythic rather than cartoon — closer to a temple carving than a
character — square or nearly so, with an expression that stays in the
:( / :| register.
Purple, and only purple, and only here. theme.h states the rule it
enforces:
normal states are calm and dark; only failure is loud. PSOGM keeps the full-bleed purple entirely to itself, which is what makes it mean something.
That purple is PSOGM_BG #4B1D9A, and it is deliberately not the accent
#7C5CFF. If Guru ever appears in accent violet on a splash, a sticker or a
README header, the deep purple stops meaning the machine stopped — and it is
the only colour in the system that means anything at all.
So: Guru does not leave the crash screen.
SchCotie — the mascot
Not drawn yet.
A daemon: the process that works while nobody is watching. The horns are a
pun on the word; the meaning is the background job that keeps running after you
have walked away — which is schinit supervising, restarting what dies, awake
at 3am. Patient and watchful rather than mischievous.
Horns carry X — POSIX, Unix, X11 — one substitution reading three ways.
Two constraints that follow from the section above. A thin X is two diagonal strokes and dissolves at small sizes, so it wants to be solid wedges with the X notched out as negative space: the horn silhouette survives downscaling and the X appears as you get closer. And it needs a turnaround — front, side, three-quarter, matching heights on shared construction lines — because a character drawn once at one angle only ever works at that angle.
The licensing point, which is not optional here
The BSD daemon is copyrighted. Marshall Kirk McKusick holds it and the terms
are not a free licence. A character that reads as "Beastie, but purple, with X
horns" is a derivative-work argument, and this mark would be in every image
SchOS ships, beside a NOTICE file this project has been careful about.
The concept is not the problem. A daemon is a Greek daimon and a Unix background process — neither is ownable. What belongs to Beastie is the execution: the pitchfork, the sneakers, that red, that face, that pose. Horns, a tail and a small imp are generic and thousands of years old.
Draw from the idea. Do not have a picture of Beastie open while you do it.
Colour
From include/theme.h, which is the source of truth. Nothing here restates a
value it does not already define.
SCH_BG |
#0C0E13 |
Ground. Near-black with a blue cast, because pure black reads as "switched off". |
SCH_FG |
#E6E8EC |
Primary text |
SCH_DIM |
#707784 |
Secondary |
SCH_ACCENT |
#7C5CFF |
The one accent. Shift, SchCotie, anything calm. |
PSOGM_BG |
#4B1D9A |
Failure only. Guru's ground and nothing else's. |
File formats
SVG, or PNG at high resolution with no lossy compression. Nothing else.
No JPEG anywhere — a mark is flat colour with hard edges, which is the exact case JPEG is worst at, and the ringing it leaves around an edge is permanent. No screenshots of marks. No re-exports of re-exports: go back to the SVG.
SVG is the source of truth for every mark. A raster is something generated from it, never edited.
What is in here, and why a raster is committed
shift.svg the logo, in colour
shift-mask.svg the same geometry in greys -- see below
shift-mask.png rasterised from it, committed on purpose
uberblock.svg SchFS
guru.svg the crash icon
superseded-*.png the old wordmark, kept for reference only
The pipeline is three stages:
shift-mask.svg --(inkscape)--> shift-mask.png --(make logo)--> include/logo.h
Both intermediates are committed, and that is deliberate. inkscape is not
a build prerequisite — see ../guides/building.md — so a
build that required a vector rasteriser would stop working on most hosts for the
sake of a file that changes about once a year. The PNG is regenerated by hand
when the SVG changes, and make logo turns it into the header.
Why the mask is a separate file from the logo
tools/python/mklogo.py reads ink as (255 - luminance) * alpha, so tones
survive as coverage rather than being flattened — and the relationship
inverts: darkest here is brightest on screen. Copying the violet fills from
shift.svg would light the object from below.
So shift-mask.svg is the same geometry in greys chosen for how the mask reads.
Two files sharing one geometry is a drift hazard; the <desc> in both says so.
If either is edited, edit both.
Where each mark is actually drawn
| Loader splash | Shift, from include/logo.h, shaded per row by metal() in boot/common/ui.c — silver, not accent. |
| Kernel console / early boot | Shift, same mask, composited flat in a theme colour by gfx_draw_logo. |
| PSOGM | Guru, drawn from primitives by draw_guru() in kernel/core/panic.c. Never a bitmap: it scales with the display and costs nothing in the kernel image. |
| Serial crash report | :(, as text. Guru cannot be drawn in ASCII, and a mood marker in a log is not the icon. |
| SchFS | Nowhere yet. uberblock.svg has no consumer; it is waiting for projects/schfs-linux/ to have a README worth heading. |
One trap, since it has already been stepped in: boot/common/ui.c includes
logo.h, theme.h and font.h, and the Makefile rule for the loader did not
list them. A new logo therefore did not rebuild the loader — make reported
nothing to do and the splash kept drawing a mask compiled months earlier. The
kernel half never showed the problem because those objects are built with
-MD -MP and track their own headers. Changing anything in here means the
loader must actually relink, and that needs clang and lld-link.
What this does not cover
- No trademark position. These are marks the project uses, not marks anyone has registered or defended.
- No usage rules for third parties — nothing says what someone else may do with them. Worth writing before anything is published.
- SchCotie does not exist. Everything above it is a brief, not a description.
- Guru is drawn but not wired in.
panic.cstill renders:(from primitives, and there is a real argument for keeping it — see the note in that file about being "legible as a mood without being a picture of anything". - No wordmark lockup is specified. "Roboto Bold beside it" is not a spacing rule, a size ratio or a clear-space margin, and it will want to be.