OSDev.org
https://forum.osdev.org/

Trouble Jumping Into Higher-Half Kernel
https://forum.osdev.org/viewtopic.php?f=1&t=32919
Page 1 of 1

Author:  nortega [ Sat May 05, 2018 6:12 am ]
Post subject:  Trouble Jumping Into Higher-Half Kernel

So I've been going through the wiki's tutorial and a few forum posts on how to get the kernel into higher-half memory, and I'm at the point where I have a multiboot entry section at 0x00100000 and the actual kernel at 0xC0100000 (as you can see in the linker script at the end of this post). When I run the kernel in QEMU it's able to run the multiboot section (which is expected), but when I jump to higher half it just gets stuck. I run an objdump on the binary file to see where exactly it'll put the higher half (it says at 0xC0103000) and I examine it in gdb with the following results:

Code:
(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)


The code I've been following is https://wiki.osdev.org/User:Glauxosdever/Higher_Half_x86_Bare_Bones mixed with the second post from https://forum.osdev.org/viewtopic.php?f=1&t=32725&hilit=higher+half.

Here's are the relevant contents of my linker script and boot.s file:
Code:
/* 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:
# 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.

Author:  Octocontrabass [ Sat May 05, 2018 6:32 am ]
Post subject:  Re: Trouble Jumping Into Higher-Half Kernel

Where are your page tables?

Author:  tabz [ Sat May 05, 2018 7:17 am ]
Post subject:  Re: Trouble Jumping Into Higher-Half Kernel

It looks like you haven't finished the tutorial as your linker script is missing some key parts, go through it again and make sure you include everything necessary from the linker script. You're also missing loads in your boot assembly file.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/