Abandoned in favor of the "kernel module" approach
Make the i386/MINE config compile again
ata: wd_readsector() was ported!
Abandoned: this approach of "DuskBSD" has been abandoned in favor of a "kernel module" approach. This repository is no longer updated.
This is a fork of the NetBSD kernel with no userland and drastic simplifications of the kernel to account for requirements that aren't part of Dusk OS design goals, that is: memory protection, security, processes, concurrency, foolproof-ness.
Instead of launching "init", it loads a raw binary (no ELF) in memory from rootfs "/kexec" and runs this in kernel memory.
To allow this binary to have access to the kernel's drivers, it passes around to this opaque binary a structure with enough addresses to go around merrily.
Read Dusk OS's NetBSD page for a rationale.
The simplification of the kernel is ongoing, here's what has been done so far:
i386
. For the refactoring ahead, this code is noise
and I'll re-add arches as needed.rump
, nfs
, netsmb
dev/wscons/wskbd.c
, function wskbd_input()
is borked to cut off link
between keyboard and wsdisplay
, and instead send these keypresses in a
buffer when is then fetched by Dusk's (key?)
routine.Not all configurations work, as many parts have been gutted. You can see an
example of a configuration that is known to work in arch/i386/conf/MINE
.
Build this kernel like you would a regular NetBSD kernel and copy it to
something like /duskbsd
.
Then, build a payload to execute. It has to be raw i386 code. Write this to
/kexec
.
Then, at boot time, drop to boot prompt and write something like boot duskbsd
.
Once the kernel is done initializing, it will load /kexec
in memory and
execute it in kernel mode.
For a convenient way to work on this kernel through QEMU, see DuskBSD Workbench.
Running a binary, right, but how to access kernel drivers and other goodies?
Through the "Kernel API" struct that is passed to kexec. Right before jumping to the kecxec payload, the kernel will push the address of that API to ESP.
You can see the struct in kern/kexec.c:KexecAPI
.
Another problem is the predictability of the address at which the kexec program
is ran. It's much more useful to have a predictable org
we can rely on so that
we can reference addresses inside the program through tomething else than
relative jumps.
The mechanism through which this is done is in a comment called "DuskBSD fixed
addressing" in kern/kexec.c
.
Here's an example NASM listing that would result in the kexec payload to print
X
to the console and then wait for a key press, then print the pressed key,
then loop forever:
ORG 0xc0430000 ; KEXECADDR
BITS 32
pop eax
pop eax
mov ebx, [eax]
mov [emit], ebx
mov ebx, [eax+4]
mov [key], ebx
push 0x58 ; 'X'
call [emit]
pop eax ; 'X'
call [key]
push eax ; typed key
call [emit]
forever: jmp forever
emit: dd 0 ; void emit(int c)
key: dd 0 ; int key()
A little reminder that NetBSD uses the System V ABI, which is necessary to keep in mind when we write the kexec payload. On i386, that means:
eax
.ebx
, esi
, edi
, ebp
, esp
are preserved by the callee, the rest are
not.