OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Jun 01, 2024 11:07 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Going crazy with my higher half kernel initialization.
PostPosted: Fri Jul 01, 2016 11:52 am 
Offline
Member
Member

Joined: Fri Jun 17, 2016 11:29 pm
Posts: 58
I'm trying to map my kernel to virtual higher half memory.

My linker script is:
Code:
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)

KERNEL_VIRTUAL_OFFSET = 0xC0000000;

SECTIONS
{
    . = 1M;
    kernel_start = .;

    start_init = .;
   .init ALIGN(4K) :
                          { *(.multiboot);
                            *(.init);
                            *(.tables);
                          }
    end_init = .;

    init_size = end_init - start_init ;

    . += KERNEL_VIRTUAL_OFFSET;

    kernel_high_half_start = .;
    /****** KERNEL *******/
   .text ALIGN(4K) :  AT(ADDR(.text) - KERNEL_VIRTUAL_OFFSET)
                         {*(.text) }
   .data ALIGN(4K) :  AT(ADDR(.data) - KERNEL_VIRTUAL_OFFSET)
                         { *(.data) }
   .bss  ALIGN(4K) :  AT(ADDR(.bss) - KERNEL_VIRTUAL_OFFSET)
                         { *(.bss)  }
    /****** KERNEL *******/
    kernel_high_half_end = .;

    kernel_end = . - KERNEL_VIRTUAL_OFFSET;
}


As you can see in the linker script, i've tackled the whole virtual/physical linker relocation issues with special sections
for initializations only.

I'm using GRUB as my bootloader, my entry point is in the
Quote:
.init
section:
Code:
bits 32
section .multiboot
;grub bootloader header
        align 4
        dd 0x1BADB002            ;magic
        dd 0x00                  ;flags
        dd - (0x1BADB002 + 0x00) ;checksum. m+f+c should be zero

global start
extern kmain          
extern paging_init

section .init

start:
  cli          ;block interrupts
  mov esp, init_stack
  call paging_init
  ; Now high half kernel is mapped to the page directory
  mov esp, stack_space   ;set stack pointer
  push ebx ; grub boot info
  call kmain

loop:
  hlt          ;halt the CPU
  jmp loop

resb 4096; 4KB small stack for my init section.
init_stack:

section .bss
resb 8192 ;8KB for stack
stack_space:


Printing a character to the screen using VGA works before calling
Code:
paging_init
, but after
Code:
paging_init
is called, the function never returns, and my kernel goes crazy.

Here are my identitiy maps of the lower 1M memory and my kernel memory:

Code:
typedef int page_table_t;
typedef int page_pointer_t;

page_table_t kernel_page_directory[PAGE_DIR_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables")));

page_pointer_t kernel_page_tables[PAGE_TABLE_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables")));

page_pointer_t identity_page_table[PAGE_TABLE_SIZE]
__attribute__((aligned(PAGE_SIZE))) __attribute__((section(".tables")));

/* Identity map the low 1M
* In early boot stage.
*/
static void __attribute__((section(".init"))) map_identity()
{
   //memset(0, identity_page_table, PAGE_TABLE_SIZE);

   unsigned int current_page = 0;
   for(int i = 0; i < BIOS_PAGE_TABLE_ENTRIES; i++, current_page += PAGE_SIZE)
      identity_page_table[i] = (current_page) | 0x3;

   current_page = 0x100000;
   for(int i = BIOS_PAGE_TABLE_ENTRIES + 1;
       i < (BIOS_PAGE_TABLE_ENTRIES + 1) + (INIT_SIZE / PAGE_SIZE);
       i++, current_page += PAGE_SIZE)
   {
      identity_page_table[i] = (current_page) | 0x3;
   }

   kernel_page_directory[0] = ((unsigned long)(identity_page_table)) | 0x3;
}

/* Map the kernel memory to its page directory,
* **in early boot stage.
* We don't need to map the init section, we don't need it anymore.
*/
__attribute__((section(".init"))) static void map_kernel_memory()
{
   //Identity map the init section
   //Start at 1MB i.e. its page aligned.
   unsigned int start_index = (INIT_SIZE / PAGE_SIZE) - 1;
   unsigned long current_page = KERNEL_VIRTUAL_START - KERNEL_VIRTUAL_OFFSET;

   for(int i = start_index;
       i < (start_index + (KERNEL_VIRTUAL_SIZE / PAGE_SIZE));
       i++, current_page += PAGE_SIZE)
   {
      kernel_page_tables[i] = current_page | 0x3;
   }

   kernel_page_directory[KERNEL_DIRECTORY_ENTRY] = (unsigned long)kernel_page_tables | 0x3;
}

__attribute__((section(".init"))) static inline void enable_paging()
{
   asm("mov eax, kernel_page_directory");

   asm("mov cr3, eax");
   asm("mov eax, cr0");

   //Turn on paging bit
   asm("or eax, 0x80000000");
   asm("mov cr0, eax");
}

__attribute__((section(".init"))) void paging_init()
{
   map_identity();

   map_kernel_memory();

   enable_paging();
}


'map_identitiy' identity maps the lower 1M(bios, bootloader, etc..) and the init and table sections, which are right after the 1M.
'map_kernel_memory' maps the higher half kernel to physical addresses.



I didn't find anything odd in my code, and i'm already in a bloody debugging session for more than 5 hours.

Any ideas, suggestions..? Thank you.

EDIT:

I have found the problematic instruction that makes my kernel reboot, all of the addresses are correct and aligned to 4K, CR3 does contain the address of my page directory, but AFTER these instructions are executed:
Code:
mov eax, cr0
or eax, 0x80000000
mov cr0, eax


the system reboots constantly.

EDIT:
Solved...
The problem was that i didn't load the GDT, although GRUB has loaded one, weird. maybe one of the segments wasn't mapped.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 90 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group