How should I begin the development of my OS?
Posted: Mon May 27, 2019 4:02 pm
I have thought out the bare bones design of the OS, namely that it should be in a sense object oriented („everything is an object”), similar in a sense to Windows NT (not identical, there are some details that will differ significantly). The following are my more specific questions:
* How to make my system bootable? I want to boot it under Qemu and Virtualbox, and have a bit of support for the emulated hardware in these products. Other virtualization products are a bonus, real hardware is beyond my dreams.
* How should I manage the physical memory? I want an advanced memory manager, capable of doing hard faults. For the hard fault implementation I may be able to fiddle, but for the actual allocation of physical memory what should I do, considering I want to be able to allocate DMA buffers too... Would a buddy allocation scheme be good or even decent?
* System call interface. What would be a simple but flexible means to implement system calls? +1 if I won't conflict with future plans of adding support for a Linux system call interface which would be separate from that of my OS. Maybe something like int 0x80, but with another number?
* x64 only. That may simplify memory management as I have quite a bit of extra space to tag segments. Right?
* All loading of executables will be done by manually mapping pages into memory of a child process from within the parent one. But how should the first process even be created? Can I include a userspace process image in the kernel itself and essentially hardcode an initial process object? How else can I do this?
* (later on) I think library loading may be a tricky topic later on. Executable file formats, similarly. But maybe by the time I fix the problems from above I may have an answer for this too?
* Objects (within the object manager) all have ACLs. Are there any optimizations that allow me to not walk the entire ACL list? Or should I just consider that ACL lists will never be significantly large for any object?
* Networking stack. Where can I find resources on how to actually implement the Ethernet, IP, IPv6, TCP, UDP protocols? (besides the University courses I took; they may be insufficient in detail). I'm not sure how Internet connections of any kind should be even provided to the user space, within the Object Manager or just to have something separate? I already think virtual memory segments which are not shared memory won't show up in the Object Manager but would the networking side be the second thing that is accessed via a separate API?
* Containers. For this OS it will be easy to set up containers: create a new root object, then create or deep-copy the structurally required objects into that and finally assign that new root object to the process that is being created. How should networking play into this? I may need to have the NICs themselves represented as objects even if they cannot be directly used via the Object Manager otherwise. Thoughts?
* What would be useful statistics that can be provided to user applications such as a future version of Task Manager or the like?
* How do I make it very easy to myself with audio? (least effort, quality shouldn't be PC speaker like but otherwise nothing special).
* Filesystem support. FAT is a bit restrictive I believe; would implementing some variant of ext, like ext2, be reasonable?
* Back to memory allocation. Above I have asked about physical memory and whether a buddy allocator is nice. Now about virtual memory, what would be the in-kernel virtual memory layout that makes my life easy? Also, I am aware about slab allocation techniques but are they sufficient for my goals?
* For USB, ACPI etc. is there any code that is nearly ready to use? I may connect a USB mouse or a USB flash storage device.
* Module loading. Modules can provide an object and, depending on the type of object provided, it would provide certain services related to that. For example a NIC, or a filesystem, or who knows what. Modules ought to mostly work even if the kernel itself is recompiled and updated with new functionality, with little necessity to rewrite them (only do incompatible changes to the module-exposed kernel API if absolutely required). I think whoever answers the executable loading question above can cover this too. Right? I guess I will have to think of a module API really besides that.
* Graphics pipeline. All graphics will be software rendered but this doesn't mean all user programs can directly access VGA memory. How should I provide graphics support to apps?
* Security. I will have 32-bit UIDs and GIDs, but ID 0 will not be considered any special. So would administrative rights be granted either via ACLs or via additional capabilities? I suspect a few things can only be done with an actual capability implementation (the possibility to override ACLs in particular, or to load kernel modules)
* For my own OS executables I will only feature 64-bit code support (and maybe, JUST MAYBE, something similar to x86_32; probably not as it can be considered an abomination by some). But if I eventually add support for Linux system calls, how would I work with 32-bit executables? [long-distance question]
I think that's it for now. I would like to be able to make it boot and load a text mode interface program within a few months. Graphical mode, not much more (but writing the actual screen compositor, even if in userspace, may be a pain). Being able to run ping on 8.8.8.8 on one of the platforms, within like 2 years. To make a decently complete userspace environment with a not-bad shell, who knows how long.
* How to make my system bootable? I want to boot it under Qemu and Virtualbox, and have a bit of support for the emulated hardware in these products. Other virtualization products are a bonus, real hardware is beyond my dreams.
* How should I manage the physical memory? I want an advanced memory manager, capable of doing hard faults. For the hard fault implementation I may be able to fiddle, but for the actual allocation of physical memory what should I do, considering I want to be able to allocate DMA buffers too... Would a buddy allocation scheme be good or even decent?
* System call interface. What would be a simple but flexible means to implement system calls? +1 if I won't conflict with future plans of adding support for a Linux system call interface which would be separate from that of my OS. Maybe something like int 0x80, but with another number?
* x64 only. That may simplify memory management as I have quite a bit of extra space to tag segments. Right?
* All loading of executables will be done by manually mapping pages into memory of a child process from within the parent one. But how should the first process even be created? Can I include a userspace process image in the kernel itself and essentially hardcode an initial process object? How else can I do this?
* (later on) I think library loading may be a tricky topic later on. Executable file formats, similarly. But maybe by the time I fix the problems from above I may have an answer for this too?
* Objects (within the object manager) all have ACLs. Are there any optimizations that allow me to not walk the entire ACL list? Or should I just consider that ACL lists will never be significantly large for any object?
* Networking stack. Where can I find resources on how to actually implement the Ethernet, IP, IPv6, TCP, UDP protocols? (besides the University courses I took; they may be insufficient in detail). I'm not sure how Internet connections of any kind should be even provided to the user space, within the Object Manager or just to have something separate? I already think virtual memory segments which are not shared memory won't show up in the Object Manager but would the networking side be the second thing that is accessed via a separate API?
* Containers. For this OS it will be easy to set up containers: create a new root object, then create or deep-copy the structurally required objects into that and finally assign that new root object to the process that is being created. How should networking play into this? I may need to have the NICs themselves represented as objects even if they cannot be directly used via the Object Manager otherwise. Thoughts?
* What would be useful statistics that can be provided to user applications such as a future version of Task Manager or the like?
* How do I make it very easy to myself with audio? (least effort, quality shouldn't be PC speaker like but otherwise nothing special).
* Filesystem support. FAT is a bit restrictive I believe; would implementing some variant of ext, like ext2, be reasonable?
* Back to memory allocation. Above I have asked about physical memory and whether a buddy allocator is nice. Now about virtual memory, what would be the in-kernel virtual memory layout that makes my life easy? Also, I am aware about slab allocation techniques but are they sufficient for my goals?
* For USB, ACPI etc. is there any code that is nearly ready to use? I may connect a USB mouse or a USB flash storage device.
* Module loading. Modules can provide an object and, depending on the type of object provided, it would provide certain services related to that. For example a NIC, or a filesystem, or who knows what. Modules ought to mostly work even if the kernel itself is recompiled and updated with new functionality, with little necessity to rewrite them (only do incompatible changes to the module-exposed kernel API if absolutely required). I think whoever answers the executable loading question above can cover this too. Right? I guess I will have to think of a module API really besides that.
* Graphics pipeline. All graphics will be software rendered but this doesn't mean all user programs can directly access VGA memory. How should I provide graphics support to apps?
* Security. I will have 32-bit UIDs and GIDs, but ID 0 will not be considered any special. So would administrative rights be granted either via ACLs or via additional capabilities? I suspect a few things can only be done with an actual capability implementation (the possibility to override ACLs in particular, or to load kernel modules)
* For my own OS executables I will only feature 64-bit code support (and maybe, JUST MAYBE, something similar to x86_32; probably not as it can be considered an abomination by some). But if I eventually add support for Linux system calls, how would I work with 32-bit executables? [long-distance question]
I think that's it for now. I would like to be able to make it boot and load a text mode interface program within a few months. Graphical mode, not much more (but writing the actual screen compositor, even if in userspace, may be a pain). Being able to run ping on 8.8.8.8 on one of the platforms, within like 2 years. To make a decently complete userspace environment with a not-bad shell, who knows how long.