Search code examples
cassemblynasmbootloaderosdev

Allocate Memory Bootloader/Assembly


I am currently trying to write a basic bootloader. The boot sector is written using assembly and it then loads and calls some C code placed in other sectors. I've also written a simple puts function. Now as a next step I try to implement some basic memory management.

I trie to write a function like malloc, it shouldn't do that much, just provide a free storage address. I think the easiest way is to just have a pointer to a free address and increase the pointer on call of the function. My only problem is where to place the data. I think it would be best to use the highest avaible address and decrement the pointer (so that a collision with stack only occures if RAM is full). But how do i get that address?
I am using the following commands to compile/run the bootloader:

nasm -f elf32 boot.asm -o boot.o
gcc -fno-PIC -ffreestanding -m16 -c main.c -o main.o 
ld -melf_i386 --build-id=none -T link.ld main.o boot.o -o kernel.elf
objcopy -O binary kernel.elf kernel.bin
qemu-system-i386 -fda kernel.bin

I didn't find anything, all assembly guides I found are using an underlying OS (malloc/brk/...)


Solution

  • For UEFI you can just use UEFI's memory manager to allocate/free memory.

    For BIOS; you start by assuming that there's usable memory from 0x0001000 (or a little lower if you don't care about page alignment) to 0x0007FFFF, except for the area your boot loader is already using. Then you ask BIOS which areas actually are RAM by getting a memory map (e.g. from "int 0x15, eax=0xE820"). Note that this memory map is variable sized (e.g. could be 10 entries at 20 bytes per entry or 200 bytes, or could be 300 entries at 24 bytes per entry or 7200 bytes, or...).

    In general; memory needed during very early boot will be statically allocated (e.g. like %define STACK_ADDRESS 0x7C00), the memory map will be obtained and stored in statically allocated memory (e.g. possibly at the end of boot loader's ".bss" section); and then you'll initialize a memory manager using the memory map you previously obtained.