~vdupras/netbsd-fiddle

Fiddling with NetBSD

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~vdupras/netbsd-fiddle
read/write
git@git.sr.ht:~vdupras/netbsd-fiddle

You can also use your local clone with git send-email.

#Fiddling with NetBSD

The goal of this repo is to play around with compiling stuff under NetBSD with a particular focus on low level interactions with the kernel.

The ultimate goal is to garner enough information about that kernel to run Dusk OS on top of it, preferably in supervisor mode so that hardware is directly accessible.

#Usage

Under NetBSD 9.3, run "make". This produces various executables with various effects. For now, my focus is i386.

#Wisdom tidbits

NetBSD follows the Sys V calling convention, that is, that call arguments are passed through the stack in reverse order (first argument in a C signature ends up on the top of the stack).

Under i386, ebx esi edi ebp esp are preserved, eax ecx edx are not. eax is the return value of the call.

Syscalls are done with int80h with eax being the ID of the syscall. A function wrapper around the interrupt is assumed! That means that unless you wrap the int80h in a function, an extra dummy push to the stack must be performed before calling int 0x80.

#How we proceed

Our goal is to produce a ELF with an executable section that is writable as well as "growable", that is, that we won't get a segmentation fault if we try to access memory beyond its initial code. We do so through the use of the objcopy utility.

The "writable exec" part is rather simple, it's only a matter of changing the flags of the .text section.

The "growable" part is more tricky. objcopy, as far as I can tell, doesn't have the ability to set the size of an existing section and it doesn't have the ability to add a section that doesn't draw its contents from a file. In other words, there is no way to create a .bss (or equivalent) section. I'm sure that more specialized ELF tools have this ability, but I'd like to stay in the core NetBSD realm.

Therefore, the solution I opted for is to "steal" a .bss section created from a dummy C program, stub.c. This C program has a single global variable with the desired size for our .bss section. Compiling this yields an object with the desired ELF section, which can then be copied to the final executable with objcopy.

We don't use symbols in our process because the binary we want to ELF-ize in Dusk OS is opaque to us: it will have been created by the in-Dusk assembler and will have to be treated as an immutable blob. Instead of symbols, we use hardcoded addresses for execution start and "here" address (the .bss section).