YeXo - een kernel programmeren

28 maart 2006

Hoeveel geheugen heeft de computer?

Het is noodzakelijk voor de kernel om te weten hoeveel RAM de computer eigenlijk heeft. Er zijn verschillende manieren om dit te bepalen: je kunt de hoeveelheid geheugen uitlezen uit het cmos. Het nadeel hiervan is echter dat de hoogste waarde die je kunt uitlezen 99mb is. Dus op een computer met 100mb RAM of meer heb je een probleem. Een tweede manier is om via bios aanroepen een overzicht van het geheugen te verkrijgen. Dit is de meestgebruikte en hieronder besproken manier. Omdat dit via interrupt moet kan dit dus alleen maar in de boatloader. Gelukkig doet grub dit al een geeft hij het resultaat door aan de geladen kernel. Een laatste manier om de hoeveelheid geheugen te bepalen is het gewoon uitproberen van het geheugen. Dit is echter lastig en wordt afgeraden omdat het vaak fout gaat.

Een overzicht van het geheugen via grub.

Zoals je waarschijnlijk weet, levert grub een structure met daarin allerlei informatie aan de kernel. Het adres van deze gegevens staat in ebx op het moment dat de kernel geladen is. Zie voor meer informatie hierover ook de multiboot standaard.

Tenslotte volgt hier nog een functie waarmee je de memory map die grub doorgeeft kunt afdrukken op het scherm. De enige fucnties die je hiervoor verder nodig hebt zijn void kprintf(char *str) en void kprinthex(unsigned long). Als je een fatsoenlijke printf functie gemaakt hebt is de code makkelijk om te zetten om die te gebruiken. unsigned long numUsablePages;

void installPaging(memory_map_t *memMap,unsigned long memMapLength){
kprintf("Kernel end address: ");
kprinthex((unsigned long)(&end));
kprintf("\nSize of memory map = ");
kprinthex(memMapLength);
kprintf("\n");

numUsablePages = 0;

memory_map_t* curMap = memMap;
while( ((unsigned long)curMap) < (((unsigned long)memMap)+memMapLength) ){
kprintf("Size=");
kprinthex(curMap->size);
kprintf(" start address=");
kprinthex(curMap->base_addr_low);
kprintf(" length=");
kprinthex(curMap->length_low);
kprintf(" type=");
kprinthex(curMap->type);
kprintf("\n");

if( curMap->type == 1 ){
numUsablePages += ((curMap->base_addr_low+curMap->length_low)>>12) - ((curMap->base_addr_low+4095)>>12);
}
curMap = (memory_map_t*) ( ((unsigned long)curMap) + curMap->size + 4 );
}
kprintf("Number of usable pages = ");
kprinthex(numUsablePages);
kprintf("\n");
}