New MicroKernel in FreeBasic
Posted: Sun May 30, 2021 2:14 pm
I am glad to announce you that i finaly managed to evolve my os kernel to an (almost) true MicroKernel in freebasic (yes yes):
* Now there is a interface API that allow the user process to handle interrupts. they tell the kernel the address of the method to call. then they should wait for an event.
* When an user handled interrupt occurs, the kernel put the request to a queue for that irq number. it will wake the owner thread up if it was waiting, (else it will left the request to the queue, and will be dequeued when the thread will be "waiting")
* When the kernel wakes the thread up, it pass the general registers to the stack of the thread, to pass them as function parameters, and changes the eip of the thread , so the method will run in the next schedule
* the user process can then do his job , and eventually modify the value of his stack (the kernel will then copy them to the "caller" thread, so he can receive returns value)
* there is also a concept of "user mode device" wich are like the interrupt handler: the thread says the kernel to create a "device" and give it an name and a descriptor (an integer wich is mainingfull only for that thread). he also give to the kernel the address of the method to call when an invoke on that device is done.
* when a process want to comunicate with the device driver, it first ask the kernel to find descriptor of the device (using its name). then it can ask the kernel to invoke the device driver by giving it the descriptor and the parameters.
* the kernel will then make the caller "waiting for reply" and wake up the device thread at the correct address
with that two concepts i managed to implement:
* user mode GUI server: it exposes it services by handling an interrupt number
* user mode driver for the keyboard and the mouse (in the GUI Server, there is 2 thread that handle the interrupt 0x20 and 0x2C to get signals from the keyboard and the mouse)
* user mode driver for the hard drive: it exposes it services using the user mode device driver interface
* user mode VFS and FAT file system: it exposes it services trought another interrupt
* Note : the kernel also provide a mechanism for the called process to map memory from/to the caller into/From his address space, in this way it can easyly copy strings (to get a button text, or a file name to open), map a buffer to the client (so he can draw on it), copy data to the client (when FileRead is called by example)
* To launch a program, the process should first load the executable into his memory, then call the kernel to create a new process using that address (the kernel will then copy it to this address space, and create a new process from it)
* i cleaned them the kernel code to remove everyting about the gui, the devices drivers, the virtual file system (and the fat file system implementation)
* the only things that remains are : the GDT initialization, the IDT initialisation, the Interrupt management , the thread management and scheduling
* the hard disk , the virtual system, and the init process are loaded by grub , and the kernel will use that to create the first processes
* to enter in graphic mode, i prepared an embedded module who is moved into the lower memory, and the kernel will use it to jump into realmode to initialize the graphic mode; this is almos the only execption to the "microkernel" structure i thing
Note: Everything is done using FreeBasic, i used my previous OS as base and made it evolved little to little to achive this. i shoud thank the creator of the Frost OS (wich is also in freebasic) from wich i took the Virtual memory management
the sources codes are on github at https://github.com/stephaneweg/onyx-kernel
* Now there is a interface API that allow the user process to handle interrupts. they tell the kernel the address of the method to call. then they should wait for an event.
* When an user handled interrupt occurs, the kernel put the request to a queue for that irq number. it will wake the owner thread up if it was waiting, (else it will left the request to the queue, and will be dequeued when the thread will be "waiting")
* When the kernel wakes the thread up, it pass the general registers to the stack of the thread, to pass them as function parameters, and changes the eip of the thread , so the method will run in the next schedule
* the user process can then do his job , and eventually modify the value of his stack (the kernel will then copy them to the "caller" thread, so he can receive returns value)
* there is also a concept of "user mode device" wich are like the interrupt handler: the thread says the kernel to create a "device" and give it an name and a descriptor (an integer wich is mainingfull only for that thread). he also give to the kernel the address of the method to call when an invoke on that device is done.
* when a process want to comunicate with the device driver, it first ask the kernel to find descriptor of the device (using its name). then it can ask the kernel to invoke the device driver by giving it the descriptor and the parameters.
* the kernel will then make the caller "waiting for reply" and wake up the device thread at the correct address
with that two concepts i managed to implement:
* user mode GUI server: it exposes it services by handling an interrupt number
* user mode driver for the keyboard and the mouse (in the GUI Server, there is 2 thread that handle the interrupt 0x20 and 0x2C to get signals from the keyboard and the mouse)
* user mode driver for the hard drive: it exposes it services using the user mode device driver interface
* user mode VFS and FAT file system: it exposes it services trought another interrupt
* Note : the kernel also provide a mechanism for the called process to map memory from/to the caller into/From his address space, in this way it can easyly copy strings (to get a button text, or a file name to open), map a buffer to the client (so he can draw on it), copy data to the client (when FileRead is called by example)
* To launch a program, the process should first load the executable into his memory, then call the kernel to create a new process using that address (the kernel will then copy it to this address space, and create a new process from it)
* i cleaned them the kernel code to remove everyting about the gui, the devices drivers, the virtual file system (and the fat file system implementation)
* the only things that remains are : the GDT initialization, the IDT initialisation, the Interrupt management , the thread management and scheduling
* the hard disk , the virtual system, and the init process are loaded by grub , and the kernel will use that to create the first processes
* to enter in graphic mode, i prepared an embedded module who is moved into the lower memory, and the kernel will use it to jump into realmode to initialize the graphic mode; this is almos the only execption to the "microkernel" structure i thing
Note: Everything is done using FreeBasic, i used my previous OS as base and made it evolved little to little to achive this. i shoud thank the creator of the Frost OS (wich is also in freebasic) from wich i took the Virtual memory management
the sources codes are on github at https://github.com/stephaneweg/onyx-kernel