Code: Select all
(gdb) x/8iw 0xc0103000
0xc0103000 <higher_kernel>: add %al,(%eax)
0xc0103002 <higher_kernel+2>: add %al,(%eax)
0xc0103004 <higher_kernel+4>: add %al,(%eax)
0xc0103006 <higher_kernel+6>: add %al,(%eax)
0xc0103008 <higher_kernel+8>: add %al,(%eax)
0xc010300a <higher_kernel+10>: add %al,(%eax)
0xc010300c <higher_kernel+12>: add %al,(%eax)
0xc010300e <higher_kernel+14>: add %al,(%eax)
Here's are the relevant contents of my linker script and boot.s file:
Code: Select all
/* linker.ld */
ENTRY(_start)
/* the virtual base for the kernel is at 3GiB */
KERNEL_VIRTUAL_BASE = 0xC0000000;
SECTIONS
{
/* kernel will be loaded into 1MiB */
. = 1M;
/* put multiboot sections at the 1MiB mark */
.multiboot_text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot_header)
*(.multiboot_text)
}
.multiboot_data BLOCK(4K) : ALIGN(4K)
{
*(.multiboot_data)
}
/*
* for the rest of the kernel we will be working in virtual
* memory at the 3GiB mark.
*/
. += KERNEL_VIRTUAL_BASE;
/* code section */
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VIRTUAL_BASE)
{
*(.text)
}
/* read-only data */
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_VIRTUAL_BASE)
{
*(.rodata)
}
/* read-write data (initialized) */
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VIRTUAL_BASE)
{
*(.data)
}
/* read-write data (uninitialized) and stack */
.bss ALIGN(4K) : AT(ADDR(.data) - KERNEL_VIRTUAL_BASE)
{
*(.bss)
}
}
Code: Select all
# boot.s
# declare constants for the multiboot header
.set ALIGN, 1 << 0 # align loaded modules on page boundaries
.set MEMINFO, 1 << 1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # the multiboot `FLAG' field
.set MAGIC, 0x1BADB002 # 'magic number' letting the boot loader know we're here
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of the above to prove we're multiboot
# the virtual base for the kernel
.set KERNEL_VIRTUAL_BASE, 0xC0000000
/*
* Declare the multiboot header marking this program as a kernel. The bootloader
* will search for these values in the first 8 KiB of the kernel file aligned at
* 32-bit boundaries (4 bytes). We put the signature in its own section to force
* it within the first 8 KiB of the kernel file.
*/
.section .multiboot_header
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .multiboot_data, "aw", @nobits
boot_page_dir:
.skip 0x1000
boot_page_tabl:
.skip 0x1000
/*
* The linker script specifies the `_start' label as the entry point to the kernel
* and the bootloader will jump to this position. That is, this is where the kernel
* starts.
*/
.section .multiboot_text, "ax", @progbits
.align 16
.global _start
.type _start, @function
_start:
/*
* TODO: start here setting up higher half memory and then call into
* a new .text section instead of this .multiboot_text section.
*/
movl $boot_page_dir, %ecx
movl %ecx, %cr3
movl %cr4, %ecx
orl $0x00000010, %ecx
movl %ecx, %cr4
movl %cr0, %ecx
orl $0x80000000, %ecx
movl %ecx, %cr0
jmp higher_kernel
/*
* Create a 16 byte aligned stack with 16 KiB of size. We create labels at the
* bottom and top of the stack.
*/
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
# HIGHER HALF
.section .text
higher_kernel:
# unmap identity mapping
movl $0, boot_page_dir + 0
# reload `%cr3' to force TLB flush
movl %cr3, %ecx
movl %ecx, %cr3
# set the position of `%esp' to the top of the stack
movl $stack_top, %esp
movl %esp, %ebp
# etc.