The following is the main part of the code, the attached is the binary file. Please help me find out what goes wrong.
Thanks.
Code: Select all
/* Multiboot constants */
.set MBOOT_ALIGN, 1 << 0
.set MBOOT_MEMINFO, 1 << 1
.set MBOOT_AOUT_KLUDGE, 1 << 16
.set MBOOT_FLAGS, MBOOT_ALIGN | MBOOT_MEMINFO | MBOOT_AOUT_KLUDGE
.set MBOOT_MAGIC, 0x1BADB002
.set MBOOT_CHECKSUM, -(MBOOT_MAGIC + MBOOT_FLAGS)
.set STACK_SIZE, 0x100000 /* 1M kernel stack! Nowadays main memory is very
* cheap, right? :-)
*/
.set PAGE_SIZE, 0x1000
/** FIXME
* We have to pack neary everything into .text section, because it seems that
* grub doesn't load content in .data section
*/
.section .text
.global start
start:
jmp bootstrap
.align 4
mbootheader:
.long MBOOT_MAGIC
.long MBOOT_FLAGS
.long MBOOT_CHECKSUM
.long mbootheader
/* Defined in ld script */
.long _ld_codeStart
.long _ld_bssStart
.long _ld_end
.long start
.align 8
taskStateSegment: /* 64-bit Task State Segment */
.long 0 /* Reserved, IGN */
.quad 0 /* RSP0 */
.quad 0 /* RSP1 */
.quad 0 /* RSP2 */
.quad 0 /* Reserved, IGN */
.quad 0 /* IST1 */
.quad 0 /* IST2 */
.quad 0 /* IST3 */
.quad 0 /* IST4 */
.quad 0 /* IST5 */
.quad 0 /* IST6 */
.quad 0 /* IST7 */
.quad 0 /* Reserved, IGN */
.short 0 /* Reserved, IGN */
.short ioMapBase - taskStateSegment /* I/O Map Base Address */
ioMapBase:
.rept 8192
.byte 0xff
.endr
.set TSS_LIMIT, . - taskStateSegment - 1
interruptDescriptorTable:
.rept 32
.quad 0
.quad 0
.endr
interruptDescriptorTablePointer:
.short . - interruptDescriptorTable - 1
.quad interruptDescriptorTable
globalDescriptorTable:
.quad 0 /* Null segment descriptor, required */
/* 32-bit Code Segment descriptor */
_32bitCodeSegmentSelector:
.long 0x0000FFFF
.long 0x00CF9A00 /* Bit G, D, P, 12, 11 and R are set, DPL is 0 */
/**
* Data Segment descriptor.
* This segment descriptor can be used both in 32-bit mode and 64-bit mode
*/
dataSegmentSelector:
.long 0x0000FFFF
.long 0x00CF9200 /* Bit G, D/B, P, 12 and W are set, DPL is 0 */
/**
* 64-bit Code Segment descriptor
*/
_64bitCodeSegmentSelector:
.long 0x00000000
.long 0x00209800 /* Bit L, P, 12 and 11 are set, DPL is 0 */
/**
* Space for 64-bit Task State Segment, we will fill content later
*/
taskStateSegmentSelector:
.quad 0
.quad 0
globalDescriptorTablePointer:
.short . - globalDescriptorTable - 1
.quad globalDescriptorTable
.code32
bootstrap:
cli
xchg %bx, %bx
mov $kernelStack, %esp
/**
* Call mangled function kernel::fillPageTable(unsigned long long*,
* unsigned long long*, unsigned long long*, unsigned long long*)
*
* Because now the CPU is still in 32-bit mode, we use 32-bit calling
* convention to call the function, the source code is also compiled
* with -m32 flag
*/
pushl $pageMapLevel4
pushl $pageDirectoryPointer
pushl $pageDirectory
pushl $pageTable
call _ZN6kernel13fillPageTableEPyS0_S0_S0_
add $0x10, %esp /* Remove function parameters from stack */
/**
* Call mangled kernel::fillTaskStateSegmentSelector(unsigned long,
* unsigned long, unsigned short*)
*/
pushl $taskStateSegmentSelector
pushl $taskStateSegment
pushl $TSS_LIMIT
call _ZN6kernel28fillTaskStateSegmentSelectorEmmPt
add $0xc, %esp /* Remove function parameters from stack */
/**
* Call mangled kernel::fillInterruptDescriptorTable
*/
pushl $(_64bitCodeSegmentSelector - globalDescriptorTable)
pushl $isrAddressTable
pushl $interruptDescriptorTable
call _ZN6kernel28fillInterruptDescriptorTableEPNS_19InterruptDescriptorEPml
add $0xc, %esp /* Remove function parameters from stack */
mov $0x1, %eax
mov %eax, %cr0
mov %cr4, %eax
bts $5, %eax /* Set PAE */
mov %eax, %cr4
mov $pageMapLevel4, %eax /* Point cr3 at pageMapLevel4 */
mov %eax, %cr3
mov $0x00C0000080, %ecx /* EFER MSR */
rdmsr
bts $8, %eax /* LME */
wrmsr
lgdt globalDescriptorTablePointer
mov %cr0, %eax
bts $31, %eax /* Enable paging */
mov %eax, %cr0
ljmp $(_64bitCodeSegmentSelector - globalDescriptorTable), $_64bitMode
.code64
_64bitMode:
cli
mov $kernelStack, %rsp
mov $(dataSegmentSelector - globalDescriptorTable), %ax
mov %ax, %ds
lidt interruptDescriptorTablePointer
mov $(taskStateSegmentSelector - globalDescriptorTable), %ax
ltr %ax
sti
/* Call mangled kernel::startKernel(void) */
call _ZN6kernel11startKernelEv /* <<============== Endless loop starts here =============== */
mov $0xB8000, %edi
mov $0x0f620f2d0f340f36, %rax
mov %rax, (%edi)
mov $0x0f6d0f200f640f69, %rax
mov %rax, 8(%edi)
mov $0x0f200f650f640f6f, %rax
mov %rax, 16(%edi)
jmp .
.macro ISR_WITHOUT_CODE isrNumber
isr\isrNumber:
push $0
push $\isrNumber
ISR_BODY
.endm
.macro ISR_WITH_CODE isrNumber
isr\isrNumber:
push $\isrNumber
ISR_BODY
.endm
.macro ISR_BODY
add $0x10, %rsp
iretq
.endm
ISR_WITHOUT_CODE 0
ISR_WITHOUT_CODE 1
ISR_WITHOUT_CODE 2
ISR_WITHOUT_CODE 3
ISR_WITHOUT_CODE 4
ISR_WITHOUT_CODE 5
ISR_WITHOUT_CODE 6
ISR_WITHOUT_CODE 7
ISR_WITH_CODE 8
ISR_WITHOUT_CODE 9
ISR_WITH_CODE 10
ISR_WITH_CODE 11
ISR_WITH_CODE 12
ISR_WITH_CODE 13
ISR_WITH_CODE 14
ISR_WITHOUT_CODE 15
ISR_WITHOUT_CODE 16
ISR_WITH_CODE 17
ISR_WITHOUT_CODE 18
ISR_WITHOUT_CODE 19
ISR_WITHOUT_CODE 20
ISR_WITHOUT_CODE 21
ISR_WITHOUT_CODE 22
ISR_WITHOUT_CODE 23
ISR_WITHOUT_CODE 24
ISR_WITHOUT_CODE 25
ISR_WITHOUT_CODE 26
ISR_WITHOUT_CODE 27
ISR_WITHOUT_CODE 28
ISR_WITHOUT_CODE 29
ISR_WITHOUT_CODE 30
ISR_WITHOUT_CODE 31
isrAddressTable:
.long isr0
.long isr1
.long isr2
.long isr3
.long isr4
.long isr5
.long isr6
.long isr7
.long isr8
.long isr9
.long isr10
.long isr11
.long isr12
.long isr13
.long isr14
.long isr15
.long isr16
.long isr17
.long isr18
.long isr19
.long isr20
.long isr21
.long isr22
.long isr23
.long isr24
.long isr25
.long isr26
.long isr27
.long isr28
.long isr29
.long isr30
.long isr31
.section .bss
.comm stackTop, STACK_SIZE, PAGE_SIZE
kernelStack: /* We just define a lable kernelStack, because stack grows
* downside
*/
.comm pageMapLevel4, PAGE_SIZE, PAGE_SIZE
.comm pageDirectoryPointer, PAGE_SIZE, PAGE_SIZE
.comm pageDirectory, 0x4000, PAGE_SIZE
.comm pageTable, 0x800000, PAGE_SIZE