Page 1 of 1

Why triple fault? I wasted a whole day in finding the cause

Posted: Sun Jul 19, 2009 10:33 am
by torshie
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

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
fillPageTable.c

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;
	}
}

Re: Why triple fault? I wasted a whole day in finding the cause

Posted: Sun Jul 19, 2009 11:28 am
by Combuster
A triple fault is not nearly enough information.

Run your code in bochs, if it crashes it will give you a dump full of information. You can also use the debugger to manually check the page table contents.

Once you know what is going wrong, it can give an indication of where it goes wrong. Which is much better than staring/stabbing/swearing at code, making random changes, and keeping your fingers crossed.

Re: Why triple fault? I wasted a whole day in finding the cause

Posted: Sun Jul 19, 2009 6:54 pm
by kop99
Hi, torshie.
If you have any bochs log, it'll help us to debug.

Re: Why triple fault? I wasted a whole day in finding the cause

Posted: Sun Jul 19, 2009 11:23 pm
by torshie
kop99 wrote:Hi, torshie.
If you have any bochs log, it'll help us to debug.
No, I use qemu to run the kernel, because I use Mac, qemu is easier to use.

I am trying to compile bochs on Mac and see what went wrong.