system calls & toolchains
Posted: Sat Jul 23, 2016 11:41 pm
This post is a bit of a rant, viewer depression advised.
In the past week or so I've been wondering where I could port my Smaller C compiler to (already self-hosting in DOS, Windows and Linux, hosting in RetroBSD). And I took a closer look at two OSes that many of you have probably heard of: xv6 (educational OS designed after UNIX) and KolibriOS (fork of MenuetOS). Why these two? Well, a few years ago someone asked on stackoverflow if there was a small C compiler for xv6 and sometime ago I noticed an archive of my compiler uploaded to a pile of KolibriOS (or MenuetOS) related files on the interwebs and then several days ago someone asked a question on this forum, which made me take a closer look at xv6.
My findings are not very encouraging so far.
xv6 issues:
* file sizes are limited to a little over 64KB, so right off the bat you just can't easily port an existing C compiler without either breaking it into smaller parts (good luck with that!) or upping the file size limit in xv6
* no lseek(), which means that all tools that work with structured binary files (such as object files and execuctables) cannot even be compiled without either being rewritten to work with files sequentially or changing xv6 to provide lseek()
* no time or rather limited time (uptime since boot), which we can live with (in theory we could ask the time from the user at OS start)
* temporary files need to be invented
* no environment/PATH
* the FPU context is not saved/restored on context switches
KolibriOS issues:
* all apps are graphical, there's no console feature in the OS, so you can't run your C programs and do read() or fprintf() using STDIN_FILENO or stdout (there's a separate user mode library that does provide some of the console window functionality and frees you from rendering letters, but it's more of a hack than a usable solution)
* naturally there's no provision for nested apps sharing the same window, so, if your compiler reports an error, it must report it within its own window (or a special system debug/log window) and it must not quit automatically, so the user can see the message
* there's no way to distinguish graphical apps from console apps, although you need that in order to handle them differently (e.g. graphical apps can be just executed and run concurrently, whereas when executing a console app you need to block the parent (if they are to share the console) until the child terminates)
* heck, there's not even a concept of file handles/descriptors (nor lseek()) at the system call level (there's yet another hacky user mode library that implements handles and fseek()/ftell() around the ugly system calls)
* the heap gives you memory in chunks of 4KB, so either you have to know in advance how much you'll need or you'll be wasting memory with small allocations; the documentation does not guarantee contiguity of the allocated chunks nor does it seem tell if physical memory is mapped in lazily during actual reads and writes, so you don't know exactly the overheads and the possible workarounds without studying the code or seeking help from the developers
* their version of FASM is graphical and can't be used with my compiler unless I'm cross-compiling for KolibriOS or making a new version of FASM for console use (if and when the right kind of console is available)
* temporary files need to be invented
* no environment/PATH
There's probably more.
So, if all that you have is just a boot sector (perhaps, even a boot loader) and odd bits of this and that, don't dare calling it an OS for clearly even more advanced OSes such as xv6 and KolibriOS appear rather unripe for consumption simply because you can't implement the standard C library for them without going through the painful experience of adding functionality in the OS or hacks and workarounds in the library. And if you can't quite develop for the OS while using it interactively or all you've got is an assembler, is it really an OS?
End of rants.
In the past week or so I've been wondering where I could port my Smaller C compiler to (already self-hosting in DOS, Windows and Linux, hosting in RetroBSD). And I took a closer look at two OSes that many of you have probably heard of: xv6 (educational OS designed after UNIX) and KolibriOS (fork of MenuetOS). Why these two? Well, a few years ago someone asked on stackoverflow if there was a small C compiler for xv6 and sometime ago I noticed an archive of my compiler uploaded to a pile of KolibriOS (or MenuetOS) related files on the interwebs and then several days ago someone asked a question on this forum, which made me take a closer look at xv6.
My findings are not very encouraging so far.
xv6 issues:
* file sizes are limited to a little over 64KB, so right off the bat you just can't easily port an existing C compiler without either breaking it into smaller parts (good luck with that!) or upping the file size limit in xv6
* no lseek(), which means that all tools that work with structured binary files (such as object files and execuctables) cannot even be compiled without either being rewritten to work with files sequentially or changing xv6 to provide lseek()
* no time or rather limited time (uptime since boot), which we can live with (in theory we could ask the time from the user at OS start)
* temporary files need to be invented
* no environment/PATH
* the FPU context is not saved/restored on context switches
KolibriOS issues:
* all apps are graphical, there's no console feature in the OS, so you can't run your C programs and do read() or fprintf() using STDIN_FILENO or stdout (there's a separate user mode library that does provide some of the console window functionality and frees you from rendering letters, but it's more of a hack than a usable solution)
* naturally there's no provision for nested apps sharing the same window, so, if your compiler reports an error, it must report it within its own window (or a special system debug/log window) and it must not quit automatically, so the user can see the message
* there's no way to distinguish graphical apps from console apps, although you need that in order to handle them differently (e.g. graphical apps can be just executed and run concurrently, whereas when executing a console app you need to block the parent (if they are to share the console) until the child terminates)
* heck, there's not even a concept of file handles/descriptors (nor lseek()) at the system call level (there's yet another hacky user mode library that implements handles and fseek()/ftell() around the ugly system calls)
* the heap gives you memory in chunks of 4KB, so either you have to know in advance how much you'll need or you'll be wasting memory with small allocations; the documentation does not guarantee contiguity of the allocated chunks nor does it seem tell if physical memory is mapped in lazily during actual reads and writes, so you don't know exactly the overheads and the possible workarounds without studying the code or seeking help from the developers
* their version of FASM is graphical and can't be used with my compiler unless I'm cross-compiling for KolibriOS or making a new version of FASM for console use (if and when the right kind of console is available)
* temporary files need to be invented
* no environment/PATH
There's probably more.
So, if all that you have is just a boot sector (perhaps, even a boot loader) and odd bits of this and that, don't dare calling it an OS for clearly even more advanced OSes such as xv6 and KolibriOS appear rather unripe for consumption simply because you can't implement the standard C library for them without going through the painful experience of adding functionality in the OS or hacks and workarounds in the library. And if you can't quite develop for the OS while using it interactively or all you've got is an assembler, is it really an OS?
End of rants.