Skip to content

Tags: vkoskiv/minima

Tags

v0.1.0

Toggle v0.1.0's commit message

Verified

This commit was signed with the committer’s verified signature.
vkoskiv Valtteri Koskivuori
meta: tag version 0.1.0

Big jump in versions, going from 0.0.10 -> 0.1.0, primarily because of
how neat my new VFS layer is. I've had a lot of fun mounting floppies
and memfs filesystems and testing stuff. Many bugs still remain, but
that's to be expected at this stage. :]

v0.0.10

Toggle v0.0.10's commit message
kernel: implement 8237 DMA controller support & floppy read command

The floppy driver can now read data off a floppy disk on bare metal,
which is really exciting! The osdev guide[1] I found did a really good
job of filling in the gaps that were left by the official Intel 8272
docs.
Plenty of things are still missing. There is no block device layer, and
the VFS stuff is still all in the userspace prototype code under
fs/ext2. Next steps are to fill in & test more FDC commands, and to put
more of the drive-specific parameters in the floppy_drive struct instead
of hard-coding them. At the moment, this can only read a full cylinder
(2 tracks) off a 1.44MB disk. It doesn't set the datarate for 720k disks
correctly yet, or even probe for the media type.

I'll also start tracking the recently added VERSION string starting from
this commit. While the initial commit of this repository is from 2021,
most of my work from 2021-2025 was short experiments, with long idle
gaps in between. In other words, I rushed to write code without having
the required knowledge to properly debug things :]

I'm retroactively assigning the following versions for significant
milestones up to this point:
- 0.0.1: initial commit + early experiments (a4d4c8a, 2021-2025)
- 0.0.2: protected mode, custom bootloader (9752a01, 2024-08-15)
- 0.0.3: userspace ext2 filesystem parser (7cfb93c, 2024-11-27)
- 0.0.4: page tables + higher-half kernel (6ce3569, 2025-07-22)
- 0.0.5: cleaned up old code, PIT & timer support (6e91ed0, 2026-02-05)
- 0.0.6: *actually* figure out GDT, dbg cmds (f835fd4, 2026-02-07)
- 0.0.7: page frame allocator + kmalloc() (eca927b, 2026-02-15)
- 0.0.8: task switching (7f428f2, 2026-02-16)
- 0.0.9: user mode & first syscalls (43a5062 & b55f0ed, 2026-02-22)
- 0.0.10: floppy driver reads tracks on bare metal (2026-03-06)

[1]: http://forum.osdev.org/viewtopic.php?t=13538

v0.0.9

Toggle v0.0.9's commit message
kernel: add syscall support

Add support for specifying privileges for IRQs, and add a new IRQ 0x80
with user privileges, and implement do_syscall() that handles
dispatching.

Nothing new about the design, it approximates what most *nix systems do
here. Usermode program sets eax to the desired syscall number, sets an
optional 0-6 arguments in ebx, ecx, edx, esi, edi and ebp, and invokes
interrupt 0x80 to perform the syscall.
The return value should be placed in eax, but that part isn't wired up
yet. Syscall table has two syscalls that just dump arguments in a
kprintf().

Very exciting addition! I can now trivially start adding stuff, probably
starting with exit() so I don't have to manually kill usermode tasks.
Maybe a sleep() would be useful too? I'd like to come up with syscalls
myself instead of copying other systems (linux), though I might end up
regretting that. We'll see.

v0.0.8

Toggle v0.0.8's commit message
kernel: Implement task switching

Buggy and barely functional, but it works. Press '9' to spawn a task,
and 'o' to kill the last task created.
There is no locking of any kind yet, which is why the background tasks
just write directly to the VGA framebuffer for now, bypassing kprintf()
machinery. The tasks just flash random ASCII characters at the top of
the screen, with increasingly long sleep() calls between iterations
multiplied by the X coord.
Very basic sleep is also in place. sleep() just sets a deadline and the
scheduler checks the deadline has elapsed before resuming a task. Not
very accurate, of course, but it's a good start.

v0.0.7

Toggle v0.0.7's commit message
kernel: Implement virtual memory mapping and kmalloc()/kfree()

I've wanted to get this far for a long time, and now it works. It's
probably far from optimal, of course, but I can now kmalloc() and
kfree() stuff, meaning I can finally move on to building other
interesting things.

Few notes:
kmalloc() checks if the allocation is <= PAGE_SIZE and calls to
pf_alloc() if that is the case. kfree() then checks the pointer it
receives to see if it's in the page frame allocator range, that is,
(>=PFA_VIRT_OFFSET), and calls pf_free().
The fallback for both is to call into the brand new vmalloc()/vmfree(),
which map out virtual address space, and allocate/free page frames as
needed. No demand paging of any kind yet, though that shouldn't be too
hard to add.

v0.0.6

Toggle v0.0.6's commit message
kernel: Finally resolve mystery triple faults

This had me stumped for a long time, until I noticed that it was
faulting on an access to the physical address of the GDT that is loaded
in the bootloader in mbr.S before jumping to stage0 in _start.c. I added
a hacky subroutine that just loads a fixed 'correct' virtual address,
which works as long as I don't change the layout of the bootloader. TODO
is to properly fix that by actually establishing a new GDT and loading
the virtual address of it.
After I fixed that, I noticed that page faults were still triple
faulting, and that as because I moved all of mman.o to the .stage0
section in 1db8d83f0 ("kernel: Actually set up and enable paging"),
which caused that code to move into low memory. I fixed it here by
shuffling mman.c code around, so now the critical stuff that sets up
page tables and the physical memory map lives in _start.o directly (with
careful attention paid to layout to preserve the jump from Cursed
Bootloader).
Now I can remove identity mapping, flush TLB and everything still works!
I added rudimentary command handling with keyboard number keys to
trigger different events, like unmapping identity, dumping the page
directory and keys to cause read/write page faults. Quite happy with
this, I think I can finally move forward to implementing more
interesting things!

v0.0.5

Toggle v0.0.5's commit message
kernel: Bare minimum PIT + timer stuff

It now somewhat accurately keeps track of system uptime with millisecond
precision, for up to ~50 days.
Hit ESC to dump current uptime to the screen.

v0.0.4

Toggle v0.0.4's commit message
kernel: Actually set up and enable paging

I think I had this working the last time I tried it, but it relied on
multiboot semantics, and I didn't really understand enough yet.

Now we map to 0xC0000000 and successfully jump to it. Bochs helped a ton
while debugging this :^)

v0.0.3

Toggle v0.0.3's commit message
kernel: fs: Redo directory dump

v0.0.2

Toggle v0.0.2's commit message
Abandon multiboot in favour of Cursed Bootloader

Cursed Bootloader is written in 16-bit real mode x86, is extremely
bugprone and lacking in features, but manages to boot this thing on
actual hardware.
It has the distinct advantage of fitting into a boot sector, which means
I can target my ancient hardware. Currently targeting my 486DX2-66 with
32MB of RAM :]

The boot sector code uses BIOS interrupts to load the raw elf image into
RAM, and then we set up protected mode and jump to and offset in there
to get to _start(). This was inspired by the way I saw it being done in
SerenityOS back in the day. Needless to say, this is very much not
recommended.