licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0
Nexoniarz is the sole author and SchOS was never published under Apache-2.0, so this is a straight relicence. LICENSE is the FSF GPLv2 text, every first-party SPDX header moves to GPL-2.0-or-later, and NOTICE, README.md, docs/licensing.md and the site say so. projects/schfs-linux follows the rest of the tree. The GPL gives copyleft: a fork has to ship its source. It also lifts the old "Linux drivers, never" rule, since GPL-2.0-only code combines with GPL-2.0-or-later. "Or later" leaves room for GPLv3, but one binary still has to pick one version, so docs/licensing.md now keeps Apache-2.0 and GPLv3 code out of the kernel to keep Linux code possible there. BSD 4-clause code goes from "avoid" to "no", because the advertising clause is GPL-incompatible. LDLS still ships no .ko. That boundary is now project policy rather than a legal requirement, and ldls.md, devices.md and licensing.md section 6 say so. refmod declares license=GPL, and ldls-check passes (27 checks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3b26575b4a
commit
26bca020b6
135 changed files with 959 additions and 689 deletions
|
|
@ -7,24 +7,31 @@ pointed here long before this file existed.
|
|||
|
||||
---
|
||||
|
||||
## 1. SchOS is Apache-2.0
|
||||
## 1. SchOS is GPL-2.0-or-later
|
||||
|
||||
Copyright Nexoniarz. See `LICENSE`.
|
||||
Copyright Nexoniarz. See `LICENSE`. Until 2026-10 SchOS was Apache-2.0; it was
|
||||
never published under that licence, and as the sole author Nexoniarz relicensed
|
||||
it outright.
|
||||
|
||||
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.
|
||||
**Why the GPL.** Two reasons, one about others and one about us:
|
||||
|
||||
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.
|
||||
- **Copyleft.** Anyone may use, study, modify and redistribute SchOS — but
|
||||
whoever ships it, or something built from it, must ship the source of that
|
||||
too, under the same terms. Under Apache-2.0 a fork could be closed and sold
|
||||
with no changes given back. The GPL does not forbid commercial use; it forbids
|
||||
taking the work private.
|
||||
- **Linux.** Linux is GPL-2.0-only, and Apache-2.0 could not be combined with
|
||||
it. Under the GPL, Linux drivers and code can be adopted (§2).
|
||||
|
||||
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.
|
||||
**Why "or later".** It keeps one door open that "only" would close: GPLv3 and
|
||||
Apache-2.0 code can still be combined with SchOS code, with that combination
|
||||
shipping under GPLv3. See §2 for why the kernel should not walk through it.
|
||||
|
||||
**What was given up.** Apache-2.0 had an express patent grant; GPLv2 has only
|
||||
an implied one. That mattered most for outside contributions, and there are
|
||||
none yet.
|
||||
|
||||
New first-party files carry `SPDX-License-Identifier: GPL-2.0-or-later`.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -36,37 +43,32 @@ date), not a wording change, and it means giving up the Apache grant.
|
|||
| 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 | — |
|
||||
| BSD **4-clause** (advertising) | **No** — see §3 | GPL-incompatible |
|
||||
| GPL-2.0-only, GPL-2.0-or-later, LGPL-2.1 | **Yes** | Source for the combined work; keep the notices |
|
||||
| MPL-2.0 | Case by case | Compatible through its secondary-licence clause, unless marked otherwise |
|
||||
| Apache-2.0, GPL-3.0, LGPL-3.0 | **Not in the kernel**; separate programs and files fine | See below |
|
||||
|
||||
**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.
|
||||
attribution record and the thing that makes the licences actually satisfied
|
||||
rather than merely tolerated.
|
||||
|
||||
### Why GPL-2.0-only is a hard no
|
||||
### One binary, one GPL version
|
||||
|
||||
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.
|
||||
"Or later" means SchOS code can go out under GPLv2 *or* GPLv3. A single linked
|
||||
binary still has to pick one:
|
||||
|
||||
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.
|
||||
- Add **Linux code** (GPL-2.0-only) and that binary is GPLv2.
|
||||
- Add **Apache-2.0 or GPLv3 code** and that binary is GPLv3, because
|
||||
Apache-2.0's patent terms are "further restrictions" under GPLv2 §6.
|
||||
|
||||
**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.
|
||||
Those two cannot meet in one binary. Linux is the main reason for the GPL, so
|
||||
**the kernel stays GPLv2-compatible**: no Apache-2.0 or GPLv3 code is linked
|
||||
into it. Userland programs are separate works, so one may be GPLv3 or
|
||||
Apache-2.0 on its own without affecting anything else.
|
||||
|
||||
**"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 [architecture/ldls.md](architecture/ldls.md), which is the layer built on exactly
|
||||
that distinction and which ships no Linux code of any kind.
|
||||
Data files such as fonts are not linked code. Roboto (Apache-2.0) sits beside
|
||||
the system as an aggregate, and that holds inside the ramdisk too: the image is
|
||||
a filesystem carried by the kernel binary, not code linked with it.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -80,7 +82,7 @@ uniformly licensed**, and the difference matters per file:
|
|||
|---|---|
|
||||
| 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 |
|
||||
| 4-clause with the advertising clause, **non-UC** copyright holder | **No.** Berkeley's rescission covers Berkeley's copyright, not other people's, and the clause is GPL-incompatible |
|
||||
|
||||
The last row is real, not hypothetical. Measured on this checkout:
|
||||
|
||||
|
|
@ -91,10 +93,9 @@ 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.
|
||||
4-clause is still permissive on its own, but the advertising clause is a
|
||||
further restriction the GPL does not allow, so **a 4-clause file cannot be
|
||||
combined with SchOS at all**. Use a 2-clause or UC-Regents file, or write it.
|
||||
|
||||
Check before copying, not after:
|
||||
|
||||
|
|
@ -128,7 +129,7 @@ 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
|
||||
Under the GPL that rules them out, and 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:
|
||||
|
|
@ -180,13 +181,13 @@ 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 SchOS, so it is the easy case: a NOTICE entry
|
||||
and nothing else.
|
||||
Roboto is Apache-2.0, which is fine for a font: it is a data file beside the
|
||||
system, not code linked into it (§2). 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
|
||||
- **The font stays under OFL** even inside a GPL-licensed 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
|
||||
|
|
@ -212,42 +213,17 @@ with SchOS. Keeping the distinction sharp is what stops it eroding:
|
|||
rebuild never needs the network; not part of any image, and not all of it is
|
||||
redistributable.
|
||||
|
||||
### The userland this rules out, and what was done instead
|
||||
### The userland, and why it is permissive anyway
|
||||
|
||||
The rule costs something real and it is worth naming the bill rather than only
|
||||
the principle.
|
||||
While SchOS was Apache-2.0, **BusyBox** (GPL-2.0-only) and **nano** (GPL-3.0)
|
||||
were ruled out, and the userland was built from toybox (0BSD), mksh and kilo
|
||||
(BSD-2-Clause) instead. Both would be possible now — nano as a separate program
|
||||
— but nothing needs replacing: toybox gives 268 applets, kilo is installed as
|
||||
`/bin/edit`, and `cmd/httpd` is first-party.
|
||||
|
||||
**BusyBox** is the obvious userland for a system this size — about four hundred
|
||||
applets, including a shell, an editor, `less` and an `httpd`. It is
|
||||
**GPL-2.0-only**, so §2 applies, and here the consequence is sharper than
|
||||
"cannot be linked": `make ramroot` links the root filesystem image *into the
|
||||
kernel binary*, so a BusyBox in `sysroot/` would put GPLv2 code inside an
|
||||
Apache-2.0 executable. Excluding it from the ramdisk avoids that and leaves the
|
||||
ramroot build with no userland at all, which is not a trade worth making.
|
||||
|
||||
**nano** is the same answer for the same reason, one version later: GPL-3.0,
|
||||
which is incompatible with Apache-2.0 in the other direction.
|
||||
|
||||
What was done instead, when the complaint "the userland is too thin" came up:
|
||||
|
||||
| wanted | answer |
|
||||
|---|---|
|
||||
| `awk`, `bc`, `diff`, `more`, `expr`, `tr`, … | already in toybox, in `toys/pending/`, switched off by `defconfig`. Turning 26 of them on took the shipped set from 236 applets to 268, at no licensing cost — it is the same 0BSD tarball. |
|
||||
| an editor that is not `vi` | [kilo](https://github.com/antirez/kilo), BSD-2-Clause, one file, no dependencies. Installed as `/bin/edit` as well as `/bin/kilo`. |
|
||||
| `wget` that works | not a userland problem at all. See below. |
|
||||
| something to host with | `cmd/httpd`, written here, Apache-2.0. |
|
||||
|
||||
The `wget` one is worth recording because it was diagnosed wrongly at first,
|
||||
and switching userland would not have fixed it: **SchOS had no DNS reachable
|
||||
from a process**, so every program taking a hostname failed and each looked
|
||||
like its own bug. BusyBox's `wget` would have failed identically. musl already
|
||||
contains a complete resolver; the only missing fact was which nameserver, which
|
||||
the kernel had all along from DHCP and never published. See
|
||||
[architecture/networking.md](architecture/networking.md).
|
||||
|
||||
The general shape: **a permissive answer existed for every one of these**, and
|
||||
three of the four were already in the tree. That will not always be true, and
|
||||
when it is not the answer is still no.
|
||||
The `wget` failure that started that discussion was not a userland problem:
|
||||
SchOS had no DNS reachable from a process, which BusyBox would have hit
|
||||
identically. See [architecture/networking.md](architecture/networking.md).
|
||||
|
||||
The mechanisms that keep this from eroding, since good intentions have already
|
||||
failed once here:
|
||||
|
|
@ -286,22 +262,26 @@ copied file is a file to be understood, attributed and maintained forever.
|
|||
|
||||
## 6. LDLS, and the distribution boundary
|
||||
|
||||
[architecture/ldls.md](architecture/ldls.md) runs Linux drivers. That sounds like it should
|
||||
contradict §2, and it does not, because the two questions below are different
|
||||
ones and only the first is about us.
|
||||
[architecture/ldls.md](architecture/ldls.md) runs Linux drivers. This section
|
||||
was written when SchOS was Apache-2.0 and the boundary below was a legal
|
||||
necessity. Under GPL-2.0-or-later it is a **project policy** instead: shipping
|
||||
a GPL-2.0-only `.ko` with SchOS would now be lawful, provided the source goes
|
||||
with it. It is still not done, because a module we never ship is a module we
|
||||
never have to vouch for, track upstream, or provide source for.
|
||||
|
||||
### LDLS is Apache-2.0
|
||||
### LDLS is ours
|
||||
|
||||
Every file under `ldls/` is ours. The loader was written from the ELF-64 gABI
|
||||
and the x86-64 psABI; the shim is written under the rule in
|
||||
[architecture/ldls.md](architecture/ldls.md). **No Linux code is in it and none ever will
|
||||
be**, which is the same standard the xHCI and USB stacks already meet (§5).
|
||||
Every file under `ldls/` is ours, GPL-2.0-or-later. The loader was written from
|
||||
the ELF-64 gABI and the x86-64 psABI; the shim is written under the rule in
|
||||
[architecture/ldls.md](architecture/ldls.md). Copying Linux code into it would
|
||||
no longer be a licence problem, but the shim's value is that it is small and
|
||||
understood, so the existing rule stands.
|
||||
|
||||
### The combination is not ours to make
|
||||
### The combination is the user's
|
||||
|
||||
| | licence | who distributes it |
|
||||
|---|---|---|
|
||||
| `ldls/` — loader, shim, host | **Apache-2.0** | us |
|
||||
| `ldls/` — loader, shim, host | **GPL-2.0-or-later** | us |
|
||||
| a `.ko` | GPL-2.0-only, usually | the user's distribution |
|
||||
| the two running together in a process | — | **nobody** |
|
||||
|
||||
|
|
@ -311,20 +291,10 @@ GPLv2 §0 is explicit about where its obligations attach:
|
|||
> by this License; they are outside its scope. **The act of running the Program
|
||||
> is not restricted.**
|
||||
|
||||
So: we ship Apache-2.0 code containing no GPL. The user obtains a GPL module
|
||||
from wherever they get their software. The user runs them together on their own
|
||||
machine. No combined work is distributed by anyone, and no GPL obligation is
|
||||
triggered — not on us, and not on them.
|
||||
|
||||
This is the position FreeBSD has shipped from for about a decade: a
|
||||
BSD-licensed `linuxkpi` in base, GPL `drm-kmod` installed by the user from
|
||||
ports.
|
||||
|
||||
**The consequence for the user, stated plainly:** they cannot redistribute the
|
||||
combination either. An image with a `.ko` baked into it is a single work that
|
||||
would have to satisfy Apache-2.0 and GPL-2.0-only at once, which §2 explains is
|
||||
impossible. That is why `RAMDISK_EXCLUDE` exists, and why `.gitignore` refuses
|
||||
`*.ko` outright — the boundary is kept mechanically rather than by intention.
|
||||
So: we ship LDLS and no modules. The user obtains a module from wherever they
|
||||
get their software and runs it on their own machine. `RAMDISK_EXCLUDE` and the
|
||||
`*.ko` rule in `.gitignore` keep that boundary mechanical rather than
|
||||
intentional.
|
||||
|
||||
### `EXPORT_SYMBOL_GPL` does not apply
|
||||
|
||||
|
|
@ -335,7 +305,7 @@ that.
|
|||
|
||||
**LDLS has no Linux symbols to gate.** `EXPORT_SYMBOL_GPL` is Linux marking
|
||||
*Linux's own* symbols, and the check it drives protects those. Every symbol
|
||||
LDLS provides is ours — reimplemented from facts, under Apache-2.0. There is no
|
||||
LDLS provides is ours — reimplemented from facts, under GPL-2.0-or-later. There is no
|
||||
gate being bypassed, because there is no Linux symbol being exposed.
|
||||
|
||||
So LDLS implements no licence check. It **reads** the module's declared licence
|
||||
|
|
|
|||
Loading…
Reference in a new issue