Why triple fault? I wasted a whole day in finding the cause
Posted: Sun Jul 19, 2009 10:33 am
I compiled boot.s into elf64-x86-64 object file and fillPageTable.c into elf32-i386 object file (with -m32 option). Then objcopy is used to convert fillPageTable.o into elf64-x86-64 format. Finally link these two elf64 object files into elf64-little kernel binary. The build process seems to be OK, though weird. But the code gets triple fault, I don't know why. I wasted a whole day on it
Please help me find out what goes wrong.
Thanks.
boot.s
fillPageTable.c
Please help me find out what goes wrong.
Thanks.
boot.s
Code: Select all
# Multiboot header
.set ALIGN, 1 << 0
.set MEMINFO, 1 << 1
.set AOUT_KLUDGE, 1 << 16
.set FLAGS, ALIGN | MEMINFO | AOUT_KLUDGE
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)
.section .text
.global start
start:
jmp boot
.align 4
mboot:
.long MAGIC
.long FLAGS
.long CHECKSUM
.long mboot
.long _$code
.long _$bss
.long _$end
.long start
.section .data
.align 8
descriptor:
.quad 0
.quad 0x0020980000000000 # Code segment
.quad 0x0000900000000000 # Data segment
gdt:
.short . - descriptor
.quad descriptor
.section .text
.code32
boot:
cli
.set STACK_SIZE, 0x100000;
mov $(stack + STACK_SIZE), %esp # Create kernel stack
push $pageMap
push $pagePointer
push $pageDirectory
push $pageTable
call fillPageTable
add $16, %esp
# Enter 64-bit mode
mov 0x11, %eax
mov %eax, %cr0
mov %cr4, %eax
bts $5, %eax # Set PAE
mov %eax, %cr4
mov $pageMap, %eax # Point cr3 at pageMap
mov %eax, %cr3
mov $0x00C0000080, %ecx # Specify EFER MSR
rdmsr
bts $8, %eax
wrmsr
mov %cr0, %eax # Enable paging
bts $31, %eax
bts $0, %eax
mov %eax, %cr0
lgdt gdt
ljmp $8, $_64bitMode
.code64
_64bitMode:
mov $(stack + STACK_SIZE), %rsp
jmp .
mov $0x00b8000, %edi
mov $0x0720077407750750, %rax
mov %rax, (%edi)
jmp .
.section .bss
.set PAGE, 4096
.comm stack, STACK_SIZE, PAGE # 1M, for kernel stack
.comm pageMap, PAGE, PAGE # Page map, page aligned
.comm pagePointer, PAGE, PAGE # Page directory pointer, page aligned
.comm pageDirectory, 0x4000, PAGE # Page directory, page aligned
.comm pageTable, 0x800000, PAGE # Page table, page aligned
Code: Select all
void fillPageTable(PageTableItem pageTable[], PageTableItem pageDirectory[],
PageTableItem pagePointer[], PageTableItem pageMap[]) {
PageTableItem fields = (1 << 0) /* P Page presents */
| (1 << 1) /* R/W Read & write access */
;
int i = 0;
for (i = 0; i < 1024 * 1024; ++i) {
pageTable[i] = (i << 12) | fields;
}
for (i = 0; i < 2048; ++i) {
pageDirectory[i] = (((long)pageTable & 0xfffff000) + i * 4096)
| fields;
}
for (i = 0; i < 4; ++i) {
pagePointer[i] = (((long)pageDirectory & 0xfffff000) + i * 4096)
| fields;
}
for (i = 4; i < 512; ++i) {
pagePointer[i] = 0;
}
pageMap[0] = ((long)pagePointer & 0xfffff000) | fields;
for (i = 1; i < 512; ++i) {
pageMap[i] = 0;
}
}