Github repo: https://github.com/kssuraaj28/OS/tree/branched_OS
I want to get a simple routine that prints out the E820 memory map, which is located at physical address 0x1000. (I get this via the BIOS int 0xE820 and store the corresponding structure at 0x1000 - my bootloader does this). I also enable paging in my bootloader as follows (Identity map + higher half map):
bits 32
%define PAGE_DIR 0x9C000
%define PAGE_TABLE_0h 0x9D000
%define PAGE_TABLE_300h 0x9E000
%define PAGE_TABLE_ENTRIES 1024
%define PRIV 3
EnablePaging:
pusha
;This makes an identity map
MakeTable0h:
mov eax, 0x0 | PRIV
mov ebx, PAGE_TABLE_0h
mov ecx, PAGE_TABLE_ENTRIES
.loop:
mov dword [ebx], eax
add ebx, 4
add eax, 4096
loop .loop
MakeTable300h:
mov eax, 0x100000 | PRIV
mov ebx, PAGE_TABLE_300h
mov ecx, PAGE_TABLE_ENTRIES
.loop:
mov dword [ebx], eax
add eax, 4096
add ebx, 4
loop .loop
MakePageDir:
mov eax, PAGE_TABLE_0h | PRIV ; 1st table is directory entry 0
mov dword [PAGE_DIR], eax
mov eax, PAGE_TABLE_300h | PRIV ; 768th entry in directory table
mov dword [PAGE_DIR+(0x300 * 4)], eax
InstallAndSwitch:
mov eax, PAGE_DIR
mov cr3, eax
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
popa
ret
Consider this routine:
static uint32_t _physical_memory_table[0x8000];
typedef struct mmap_entry
{
uint32_t startLo;
uint32_t startHi;
uint32_t sizeLo;
uint32_t sizeHi;
uint32_t type;
uint32_t acpi_3_0;
} mmap_entry_t;
void print_mmap(uint32_t mapentrycount)
{
mmap_entry_t* map_ptr= (mmap_entry_t*)PMMAP; //PMMAP is 0x1000
uint32_t* z = (uint32_t*) 0x1000;
for (int i = 0; i< mapentrycount ; i++)
{
printf("\nStarting address:"); printhex((map_ptr+i) -> startLo);
printf("\tSize: "); printhex((map_ptr+i) -> sizeLo);
printf("\tType:"); printhex((map_ptr+i) -> type);
}
for (uint32_t i=0;i<0x8000;i++)
_physical_memory_table[i] = 0xffffffff;
}
Note: printf and printhex are user defined functions that print a string and an integer respectively.
I use qemu as my emulator. I also tested this code in real hardware. It works. The issue is when I do this (I change the order of the for loops):
{
for (uint32_t i=0;i<0x8000;i++)
_physical_memory_table[i] = 0xffffffff;
uint32_t* z = (uint32_t*) 0x1000;
for (int i = 0; i< mapentrycount ; i++)
{
printf("\nStarting address:"); printhex((map_ptr+i) -> startLo);
printf("\tSize: "); printhex((map_ptr+i) -> sizeLo);
printf("\tType:"); printhex((map_ptr+i) -> type);
}
}
The code works on qemu, but on the real machine, all my printhex calls print out 0xffffffff.
Where could I be going wrong?
Some other functions:
void printhex(uint32_t input)
{
char buffer[11] = "0x00000000"; //0x + 8 + null
uint8_t pointer = 9;
for(int i=0;i<8;i++)
{
int c = input & 0xF;
if(c<10)
c+=0x30;
else
c+=55;
buffer[pointer] = (char)c;
pointer --;
input >>=4;
}
printf(buffer);
}
void printf(char* Message)
{
uint32_t pointer = get_cursor();
pointer <<= 1;
char* vga_cursor = (char*) VIDEO_MEMORY;
vga_cursor += pointer;
while (*Message)
{
char c=*Message;
*vga_cursor = *Message;
Message++;
vga_cursor ++;
*vga_cursor = current_color;
vga_cursor ++;
}
}
vga_cursor -= VIDEO_MEMORY;
pointer = (uint32_t)vga_cursor;
pointer >>= 1;
set_cursor(pointer);
}
The main issue is that the code is working on the emulator but not on hardware, what are the reasons for this?
Edit: I was doing a bit of troubleshooting and this looks like an A20 error to me... I think I've not enabled it right or something
User contributions licensed under CC BY-SA 3.0