RSoC: FAT32 Filesystem in Redox - 2

By Deepak Sirone on

This is the second blog post about implementing a FAT32 filesystem in Redox. In the previous blog post the future work was detailed as follows:

TODO

Initially the idea was to write a stub from the ground up and the reason behind this was to minimize the code size in order to have a fast boot. But it turned out to be very tedious and a lot of the work was already done in the Redox kernel. The fully fledged Redox kernel is about 8.6 MB in size. So the effort was on to strip down the Redox kernel to just support what was necessary to have disk reads.

Stripping down the kernel started with the serial console debug support. Qemu maps the serial console to stdio with the -serial mon:stdio option. The serial console code depended on the arch submodule and the syscall crate and they were pulled in. After the arch submodule was pulled in I realized that all the subsystems initialized in the kstart function in start.rs would be useful at some point. So I began to get each of the subsystems working.

Getting the paging and the GDT initializations to work was straightforward. Setting up the IDT required that all the external interrupt handlers be disabled. Syscalls are completely disabled as the INT 80h handler is mostly commented out.

With the base stub ready I started working on getting disk reads working. Initially the idea was to port the ahci driver such that it dosen’t make use of Redox schemes. Again that meant a near complete rewrite of the driver and after discussions with @jackpot51 it was decided that the disks should be read after dropping to real mode, using BIOS interrupts.

To do this I referred to the OsDev article here. The code should be loaded to a location which can be addressed in real mode i.e. a usable chunk of memory below the 1MB mark. The pages where the code is loaded should be both executable and writable as there is an interleaving of code and data. The stub adaptation of this code is here.

Roughly the code works as follows:

The real mode is loaded at address 0xb000 during booting. The pages starting from 0x9000 and 0xa000 are used for the real mode stack. The pages starting from 0xc000 upto 0x70000 can be used to read in disk data. This gives a total of 11 pages(each page being 4096 bytes) worth of disk data per drop into real mode. After some more testing the code can be moved further towards the bootsector ending address of 0x7e00 giving more disk data per drop.

Before dropping to real mode from the stub, all the pages from 0x9000 upto 0x70000 are identity mapped and given write permission in the init_real_mode function. The function which drops to real mode can be found here

The drop works as follows:

The stub is currently about 250K in size. There is still a lot of code which can be eliminated to make the code even smaller. For some reason printing in real mode using INT 10h causes the far jmp into long mode to fail.

Future Work

Miscellaneous Stuff