docs/plan/ldls.md. SchOS cannot write a driver for every device that exists
and no project can, so the only route to the hardware support an established
system has is to run Linux's. hybrid.md built the mechanisms for this and said
so; vgpud proved them. This is what they were for.
Five rules, and everything else is an implementation of them:
1. Nothing GPL ever enters an image we build. The driver is the user's,
obtained by them, loaded on their machine.
2. It runs in a process, never in the kernel. Legally a module linked into
our kernel is the strongest derivative-work argument that exists, and
practically this is foreign code that must not be able to take the
machine. FreeBSD has shipped from this position for a decade.
3. Facts, not expression. A symbol's signature and a struct's offsets are
facts a compiled driver depends on; comments, macro bodies and inline
bodies are expression and are never carried over. Provenance recorded per
file. Flagged in the doc as wanting real legal advice before shipping.
4. One kernel version at a time, pinned and named, because Linux says in
writing that it has no stable in-kernel ABI.
5. The unresolved-symbol list is the specification. Load a real module and
let the loader say what is missing rather than guessing the surface.
Four pieces: an ELF relocatable loader (ours, clean, no licence question), the
KPI shim (the actual work), /dev/pci as the back end (built), and one new
kernel interface -- a netdev whose backend is a process, which is the exact
analogue of display_ops and is four vtable entries wide.
First target is 8139too rather than r8169, and the reason is decisive: QEMU
emulates rtl8139 and does not emulate r8169, so the obvious choice cannot be
tested at all. 8139too is also smaller, needs no firmware, and uses the thin
mii helpers instead of dragging in phylib. r8169 is what proves it was general,
afterwards and much more cheaply.
The "what it will not do" section carries the honest list, including the two
that are not yet answered: no EXPORT_SYMBOL_GPL story, and no IOMMU -- which
for foreign drivers is a materially worse problem than for our own, and is the
strongest argument for one this project has produced.
hybrid.md is closed and leaves the register; ldls.md takes the slot, which is
the freeze rule working rather than being bent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
246 lines
11 KiB
Markdown
246 lines
11 KiB
Markdown
# Licensing
|
|
|
|
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. SchOS is Apache-2.0
|
|
|
|
Copyright Nexoniarz. See `LICENSE`.
|
|
|
|
Apache-2.0 was chosen over MIT/BSD for one reason that actually matters at OS
|
|
scale: it contains an **express patent grant** and a patent-retaliation clause.
|
|
MIT and BSD are silent on patents, which means a contributor can hand you code
|
|
and later assert a patent over it. For a kernel that is intended to accept
|
|
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
|
|
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
|
|
(a bespoke proprietary licence, or something like BUSL-1.1 with a conversion
|
|
date), not a wording change, and it means giving up the Apache grant.
|
|
|
|
---
|
|
|
|
## 2. What can be copied in
|
|
|
|
| Licence | Verdict | Obligation |
|
|
|---|---|---|
|
|
| Public domain, 0BSD, CC0 | **Yes** | None |
|
|
| MIT, ISC | **Yes** | Keep the notice |
|
|
| BSD 2-clause | **Yes** | Keep the notice |
|
|
| BSD 3-clause | **Yes** | Keep the notice; no endorsement claims |
|
|
| BSD **4-clause** (advertising) | **Avoid** — see §3 | Notice *and* an acknowledgement in advertising materials |
|
|
| Apache-2.0 | **Yes** | Keep NOTICE contents |
|
|
| MPL-2.0 | Case by case | File-level copyleft; keep those files separate |
|
|
| **GPL-2.0-only** | **No** | — |
|
|
| **GPL-3.0 / LGPL-3.0** | **No** for linked code | — |
|
|
|
|
**Every "yes" above requires an entry in `NOTICE`.** That file is the project's
|
|
attribution record and the thing that makes the permissive licences actually
|
|
satisfied rather than merely tolerated.
|
|
|
|
### Why GPL-2.0-only is a hard no
|
|
|
|
Apache-2.0 imposes conditions GPLv2 treats as "further restrictions" under its
|
|
§6 — principally the patent-retaliation term. The FSF and the ASF agree on
|
|
this: **Apache-2.0 code and GPL-2.0-only code cannot be combined into one
|
|
distributable work.** It is not a matter of taste or of how carefully the files
|
|
are kept apart in the tree; it is that the combined binary cannot satisfy both
|
|
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
|
|
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
|
|
specification rather than ported.
|
|
|
|
**"Cannot be adopted" is not the same as "cannot be run."** A driver the *user*
|
|
obtains and loads on their own machine is their act, not a distribution by us —
|
|
see §4 and [plan/ldls.md](plan/ldls.md), which is the layer built on exactly
|
|
that distinction and which ships no Linux code of any kind.
|
|
|
|
---
|
|
|
|
## 3. NetBSD in particular
|
|
|
|
`src-trunk/` is a NetBSD checkout kept as reference material and a parts bin
|
|
(see [plan/schapi.md](plan/schapi.md) §5). NetBSD is **not
|
|
uniformly licensed**, and the difference matters per file:
|
|
|
|
| Template | Status |
|
|
|---|---|
|
|
| 2-clause BSD — modern NetBSD Foundation files | **Fine** |
|
|
| 3-clause, "Regents of the University of California" | **Fine.** Berkeley formally rescinded the advertising clause in 1999 |
|
|
| 4-clause with the advertising clause, **non-UC** copyright holder | **Avoid.** Berkeley's rescission covers Berkeley's copyright, not other people's |
|
|
|
|
The last row is real, not hypothetical. Measured on this checkout:
|
|
|
|
```
|
|
sys/kern 26 of 220 files carry the advertising clause
|
|
sys/dev 500 of 3565
|
|
lib/libc 101 of 1575
|
|
sys/net 5 of 180 ← the TCP/IP stack is nearly clean
|
|
```
|
|
|
|
4-clause is still permissive and still redistributable; the burden is an
|
|
advertising obligation that accumulates quietly and is tedious to honour
|
|
properly. Prefer a 2-clause or UC-Regents file. If a 4-clause file is genuinely
|
|
the right answer, it goes into `NOTICE` with the full clause quoted.
|
|
|
|
Check before copying, not after:
|
|
|
|
```sh
|
|
grep -l "All advertising materials" <file>
|
|
```
|
|
|
|
### And check *whose* clause it is
|
|
|
|
A file can carry several licence blocks from several copyright holders. Finding
|
|
the advertising clause is only half the check — Berkeley's rescission covers
|
|
Berkeley's copyright and nobody else's, so the question is always *whose*
|
|
clause you found.
|
|
|
|
Measured on `src-trunk`, the networking tree:
|
|
|
|
```
|
|
sys/net 106 files, 5 with the advertising clause
|
|
sys/netinet 121 files, 25 " " "
|
|
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 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.
|
|
|
|
**But `tcp_input.c` and `tcp_output.c` are not.** Their advertising clause
|
|
belongs to the **WIDE Project** (the KAME IPv6 people), whose copyright sits at
|
|
the top of the file; the UC block is a separate licence further down. Berkeley
|
|
never spoke for WIDE, so the rescission does not reach it. The two most
|
|
valuable files in the stack are the two encumbered ones.
|
|
|
|
That is not fatal — 4-clause is still permissive — but it is exactly the case
|
|
where a **second BSD tree earns its disk space**: FreeBSD's TCP has been
|
|
through a relicensing effort NetBSD's has not, so the same file there may well
|
|
be 2-clause. Check it the same way before assuming either:
|
|
|
|
```sh
|
|
grep -n "Copyright" <file> | head # who claims it
|
|
grep -n -B6 "All advertising" <file> # whose clause is it
|
|
```
|
|
|
|
### FreeBSD's TCP is clean where NetBSD's is not
|
|
|
|
Checked, 2026-08-08, exactly that way. Against FreeBSD `main`:
|
|
`sys/netinet/tcp_input.c` contains **no advertising clause at all**. Its
|
|
copyright holders are the UC Regents, Swinburne University, Lawrence Stewart,
|
|
the FreeBSD Foundation and Juniper Networks -- all BSD-2 or BSD-3.
|
|
|
|
So if BSD networking code is taken, it must come from **FreeBSD, not NetBSD**,
|
|
and the specific reason is TCP. This reverses the earlier assumption in
|
|
`docs/plan/roadmap.md` that NetBSD was the intended starting point; NetBSD remains
|
|
the better-written reference to *read*, but FreeBSD is the one that can be
|
|
copied from.
|
|
|
|
|
|
### The third option: lwIP
|
|
|
|
Before porting either BSD stack, weigh **lwIP** against both. Verified
|
|
2026-08-08 from its `COPYING`: 3-clause BSD, Swedish Institute of Computer
|
|
Science, **no advertising clause anywhere in the file**. Compatible, one NOTICE
|
|
entry, done.
|
|
|
|
The licence is the smaller half of the argument. The larger half is that
|
|
FreeBSD's `sys/netinet` is not a library -- `tcp_input.c` alone is 122 KB and
|
|
reaches into mbufs, `epoch(9)`, netisr, VNET, `uma(9)`, sockbufs, inpcb hash
|
|
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/guides/adding-a-driver.md` already reached about `sys/dev/usb`.
|
|
|
|
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.
|
|
|
|
### Fonts
|
|
|
|
Chosen 2026-08-09, both licences checked at source rather than assumed:
|
|
|
|
| Font | Where | Licence |
|
|
|---|---|---|
|
|
| Roboto | desktop, window manager, compositor | **Apache-2.0** |
|
|
| JetBrains Mono | terminal, TTY | **SIL OFL 1.1** |
|
|
|
|
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
|
|
worth knowing before anyone subsets or converts a font:
|
|
|
|
- **The font stays under OFL** even inside an Apache-2.0 system. It does not
|
|
infect anything else; it just cannot be relicensed.
|
|
- **It may not be sold on its own.** Shipping it as part of an OS is fine.
|
|
- **Reserved Font Names.** JetBrains Mono declares *none* -- its copyright line
|
|
names no reserved name -- so a modified version may keep the name. Most OFL
|
|
fonts do reserve theirs, and then a derivative must be renamed.
|
|
Pre-rasterising a font into bitmaps at build time **is** a modification, so
|
|
this is not a theoretical point for this project.
|
|
|
|
---
|
|
|
|
## 4. Things that are deliberately not shipped
|
|
|
|
Some code is fine to *build and run locally* and impossible to *distribute*
|
|
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
|
|
directory name is spelled as it is on disk; renaming it is a one-line change
|
|
if it ever grates.
|
|
- **`src-trunk/`** — a NetBSD checkout, same rules. Currently absent; it was
|
|
deleted for disk space and can be re-fetched sparsely if needed.
|
|
- **`dist/`** — upstream tarballs and other downloaded blobs. Cached so a
|
|
rebuild never needs the network; not part of any image, and not all of it is
|
|
redistributable.
|
|
|
|
The mechanisms that keep this from eroding, since good intentions have already
|
|
failed once here:
|
|
|
|
- `NOTPORTS` in `ports/Makefile` — a port that lives in the tree but is never
|
|
built by `make`.
|
|
- `RAMDISK_EXCLUDE` in the root `Makefile` — paths kept out of the ramdisk root.
|
|
This one matters more than it looks: the ramdisk image is linked *into the
|
|
kernel binary*, so anything sitting in `sysroot/` when that image is built
|
|
becomes part of a distributable artifact. A GPL-2.0 or non-redistributable
|
|
file staged there does not merely ride along, it makes the kernel itself
|
|
undistributable.
|
|
|
|
A previous acceptance test — a ported 1993 shooter, GPL-2.0 engine on
|
|
non-redistributable shareware data — was carried under exactly these rules and
|
|
has since been removed. It is worth recording *why* it was safe: it was never in
|
|
`PORTS`, and its 33 MB of data was excluded from the ramdisk. It is equally
|
|
worth recording that the safety depended on two separate opt-outs staying
|
|
correct, which is a lot of standing risk for a test that had stopped finding
|
|
bugs. See `docs/guides/testing.md`.
|
|
|
|
---
|
|
|
|
## 5. Specifications are not code
|
|
|
|
A published specification carries no copyright over an independent
|
|
implementation of it. The xHCI, USB, PCI, fbdev and ELF specifications were all
|
|
read and implemented directly, which is why those drivers have no licence
|
|
entanglement at all despite equivalents existing in both Linux and BSD.
|
|
|
|
When a subsystem is small enough to write from the spec, that is usually the
|
|
cheapest option in the long run — not because copying is hard, but because a
|
|
copied file is a file to be understood, attributed and maintained forever.
|