Memory map

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
derva
Posts: 8
Joined: Sat Oct 19, 2024 3:46 pm

Memory map

Post by derva »

Hi guys,

I'm still new here. I'm having issues with how to detect memory map for my operating system. I read about it, and i kinda get how to implement Virtual Memory Map (page directory, page table, offset, etc) but I'm really having trouble wrapping this one.

So, I really tried before asking this question.
As far as I understand there's a few things in game here. BIOS, bootloader, kernel.

BIOS is first thing starting when there is power, and it test some hardware components (CPU, memory, etc).
After that Bootloader gets in, trying to load OS/kernel into memory, bootloader is in ROM.
Then kernel boots it up and we have OS.

My understanding how to get memory map is something like this. We need to put in EAX register E820h, and then call BIOS 0x15 - this two 'instructions' will return to me one memory map, then i need to iterate it through until I get all memory maps.
But i'm not sure how to do this.

If I start it (`qemu-system-i686 -kernel os.bin` it keeps failing )

Code

boot.s

Code: Select all

/* Declare constants for the multiboot header. */
.set ALIGN,    1<<0             /* align loaded modules on page boundaries */
.set MEMINFO,  1<<1             /* provide memory map */
.set FLAGS,    ALIGN | MEMINFO  /* this is the Multiboot 'flag' field */
.set MAGIC,    0x1BADB002       /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:

.section .text
.global _start
.type _start, @function
_start:
	/* for some odd way it works only with AT&T assembler style, i'll check that later */
	mov $0xE820, %eax
	int $0x15 /* call BIOS function*/
	
	/* what to do there really? */

	mov $stack_top, %esp

	call kernel_main
	cli
1:	hlt
	jmp 1b

.size _start, . - _start

kernel.c

Code: Select all


typedef struct multiboot_memory_map {
	unsigned int size;
	unsigned int base_addr_low,base_addr_high;
	unsigned int length_low,length_high;
	unsigned int type;
} multiboot_memory_map_t;

typedef multiboot_memory_map_t mmap_entry_t;

void kernel_main(multiboot_info* mbt, unsigned int magic) {
	mmap_entry_t* entry = mbt->mmap_addr;
	while(entry < mbt->mmap_addr + mbt->mmap_length) {
		entry = (mmap_entry_t*) ((unsigned int) entry + entry->size + sizeof(entry->size));
	}


	terminal_initialize();
	/* Initialize terminal interface */
	initGdt(); //init gdt

	/* Newline support is left as an exercise. */
	terminal_writestring("Hello World!");
}
Any hints and support are appreciated :D

Thanks, derva
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Memory map

Post by Octocontrabass »

derva wrote: Mon Nov 18, 2024 3:18 pmMy understanding how to get memory map is something like this. We need to put in EAX register E820h, and then call BIOS 0x15 - this two 'instructions' will return to me one memory map, then i need to iterate it through until I get all memory maps.
But i'm not sure how to do this.
You don't. That's how a legacy BIOS bootloader gets the memory map. You're not writing a legacy BIOS bootloader, so you can forget everything about BIOS interrupts.

You're using QEMU's built-in Multiboot bootloader, so you only need to follow the Multiboot specification to get a memory map. You already have part of the code written, but your kernel_main expects two arguments and your startup code isn't passing any arguments.
derva
Posts: 8
Joined: Sat Oct 19, 2024 3:46 pm

Re: Memory map

Post by derva »

lol, I think I get it now, whoooa

Thanks man, a lot, I'll try this first thing tomorrow :)
Post Reply