Przy włączeniu stronnicowania w BOCHS'ie następne ładowanie instrukcji odbywa się spod adresu ??? (physical address not available). Kod jest taki:
KERN.ASM
[BITS 32]
[global start]
[extern main]
[SECTION .text]
start:
mov esp, 0xc0f00000
mov ebp, esp
push 0x20C00
push 0xC007F400 ; Only first 32 MB is usable, say it to kernel
call main
cli
hlt
[global storeb] ; Reverse Order ( Destination, Size, Value)
storeb:
push ebp
mov ebp, esp
push edi
push ecx
push eax
mov edi, [ebp+8]
mov ecx, [ebp+12]
mov al, byte [ebp+16]
rep stosb
pop eax
pop ecx
pop edi
pop ebp
ret
[global poked]
poked:
push ebp
mov ebp, esp
push eax
push ebx
mov ebx, [ebp+8]
mov eax, [ebp+12]
mov dword [ds:ebx], eax
pop ebx
pop eax
pop ebp
ret
[global init_os]
init_os:
push ebp
mov ebp, esp
push eax
mov eax, [ebp+8]
mov cr3, eax
mov eax, cr0
or eax, 0x80000000 ; Set Paging Bit
mov cr0, eax ; Fire PAGING!
<b> I tu właśnie fetch następuje spod ??? Stos nie jest mapowany do przestrzeni adresowej, ale jak wsadzi tu NOP'a to też nie działa</b>
pop eax
pop ebp
ret
KERNEL.C
extern void init_os(unsigned int pgdir_addr);
extern void writecr3(unsigned int cr3);
extern unsigned int readcr3();
extern void pokeb(unsigned int address, unsigned char value);
extern void pokew(unsigned int address, unsigned short int value);
extern void poked(unsigned int address, unsigned int value);
extern unsigned char peekb(unsigned int address);
extern void memcpy(unsigned int start, unsigned int destination, unsigned int size);
extern void storeb(unsigned char value, unsigned int size, unsigned int destination);
void write_pe(unsigned int address, unsigned short int number, unsigned int pointer, unsigned char mode)
{
poked(address+number*4, 0); // Format the Area
poked(address+(number*4), (pointer*2048)+mode);
}
int main(unsigned int mem_start, unsigned int mem_size)
{
storeb(0x00,0x20000,0xC007F000); // Format VMM Table
storeb(0xFF,0x00020,0xC007F000); // Reserve first megabyte
storeb(0xFF,mem_size,mem_start); // Mark unavailable memory
// Write Management Zone PGTBL #1 to PGDIR
write_pe(0xC007E000,960,0x0007C000,11);
// Write Kernel Code PGTBL #1 to PGDIR
write_pe(0xC007E000,768,0x0007D000,11);
// Write Kernel Page #1 to Kernel Code PGTBL
write_pe(0xC007D000,000,0x00000000,9);
init_os(0x0007E000);
}
Gdzie jest błąd? Może funkcja do zapisu PGE i PTE działa źle, czy coś innego tam siedzi?