Higher Half kernel linker problems
Posted: Sun Sep 09, 2007 6:08 pm
I'm having some trouble getting my linker script to work right.
Everything is working correctly except for the fact that after the jump to the higherHalf label, it's not actually running at the higher half. I know this because Bochs reports that my EIP is at location "EIP=000001fa" when I kill bochs.
This is my kernel entry point (start.s):
This is my linker script:
Here's what bochs reports:
Everything is working correctly except for the fact that after the jump to the higherHalf label, it's not actually running at the higher half. I know this because Bochs reports that my EIP is at location "EIP=000001fa" when I kill bochs.
This is my kernel entry point (start.s):
Code: Select all
# This is the Kernel entry point
# At this point, GDT should be set up and we should be in protected mode
.section .start
.text
.global kernel_start
.code32
kernel_start:
# Set up Segment Registers
movw $0x0010, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
call k_install_paging
# Set up kernel stack (2MB at HigherHalf)
movl $0x801FFFFF, %ebp
movl $0x801FFFFF, %esp
jmp HigherHalf
.text
HigherHalf:
call k_main
hang:
jmp hang
# Include the ISR and IRQ stubs
.include "boot/interrupts.inc"
Code: Select all
ENTRY( kernel_start )
OUTPUT_FORMAT( binary )
SECTIONS
{
. = 0x0;
.start 0x0 : AT(0x0)
{
*(.start)
. = ALIGN( 4096 );
}
.text 0x80000000 + SIZEOF( .start ) : AT( ADDR( .start ) + SIZEOF( .start ) )
{
*(.text)
*(.rodata*)
*(.gnu.linkonce.r.*)
}
.data ADDR( .text ) + SIZEOF( .text ) : AT( LOADADDR( .text ) + SIZEOF( .text ) )
{
*(.data)
}
.bss ALIGN( ADDR( .data ) + SIZEOF( .data ), 4096 ): AT( LOADADDR( .data ) + SIZEOF( .data ) )
{
*(.bss .bss.*)
*(COMMON)
}
}
Code: Select all
00092426000i[CPU0 ] protected mode
00092426000i[CPU0 ] CS.d_b = 32 bit
00092426000i[CPU0 ] SS.d_b = 32 bit
00092426000i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=0000002e EDX=00000f56
00092426000i[CPU0 ] | ESP=801fffef EBP=801ffff7 ESI=00002000 EDI=00002000
00092426000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df IF tf SF zf AF pf cf
00092426000i[CPU0 ] | SEG selector base limit G D
00092426000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00092426000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00092426000i[CPU0 ] | EIP=000001fa (000001fa)
00092426000i[CPU0 ] | CR0=0x80000011 CR1=0 CR2=0x00000000
00092426000i[CPU0 ] | CR3=0x00091000 CR4=0x00000000
00092426000i[CPU0 ] >> jmp .+0xfffffffe (0x000001fa) : EBFE
00092426000i[ ] restoring default signal behavior