2016-08-16 20 views
0

我刚刚在qemu上完成高半程。但由于某种原因,给我错误虚拟盒和波奇:入口点不在一个段

entry point isnt in a segment. 

please press any key to continue . . . 

但在Qemu它的工作都很好。那么这里是我定义我的切入点,我的链接脚本:

/* The bootloader will look at this image and start execution at the symbol 
    designated as the entry point. */ 
ENTRY(loader) 

SECTIONS { 
    /* The kernel will live at 3GB + 1MB in the virtual 
     address space, which will be mapped to 1MB in the 
     physical address space. */ 
    . = 0xC0100000; 


    .text ALIGN (0x1000) : AT(ADDR(.text) - 0xC0000000) { 
     *(.multiboot) 
     *(.text) 
     *(.rodata*) 
    } 

    .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) { 
     start_ctors = .; 
     KEEP(*(.init_array)); 
     KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))); 
     end_ctors = .; 
     *(.data) 
    } 

    .bss : AT(ADDR(.bss) - 0xC0000000) { 
     _sbss = .; 
     *(COMMON) 
     *(.bss) 
     _ebss = .; 
    } 
} 

和我boot.asm(GRUB):

;Global MultiBoot Kernel Recongnzation 
MAGIC equ 0x1badb002 
FLAGS equ (1<<0 | 1<<1) 
CHECKSUM equ -(MAGIC + FLAGS) 


;Putting in object file 
section .multiboot 
    dd MAGIC 
    dd FLAGS 
    dd CHECKSUM 

section .data 

KERNEL_VIRTUAL_BASE equ 0xC0000000     ; 3GB 
KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; Page directory index of kernel's 4MB PTE. 

align 0x1000 
BootPageDirectory: 
    ; This page directory entry identity-maps the first 4MB of the 32-bit physical address space. 
    ; All bits are clear except the following: 
    ; bit 7: PS The kernel page is 4MB. 
    ; bit 1: RW The kernel page is read/write. 
    ; bit 0: P The kernel page is present. 
    ; This entry must be here -- otherwise the kernel will crash immediately after paging is 
    ; enabled because it can't fetch the next instruction! It's ok to unmap this page later. 
    dd 0x00000083 
    times (KERNEL_PAGE_NUMBER - 1) dd 0     ; Pages before kernel space. 
    ; This page directory entry defines a 4MB page containing the kernel. 
    dd 0x00000083 
    times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0 ; Pages after the kernel image. 


section .text 
    extern kernelMain 
    extern callConstructors 
    extern page_directory 
    extern pages_init 
    ; reserve initial kernel stack space -- that's 16k. 
    STACKSIZE equ 0x4000 
    ; setting up entry point for linker 
    loader equ (_loader - 0xC0000000) 
    global loader 

     _loader: 
        ;Enable Paging START 

        ; NOTE: Until paging is set up, the code must be position-independent and use physical 
        ; addresses, not virtual ones! 
        mov ecx, (BootPageDirectory - KERNEL_VIRTUAL_BASE) 
        mov cr3, ecx          ; Load Page Directory Base Register. 

        mov ecx, cr4 
        or ecx, 0x00000010       ; Set PSE bit in CR4 to enable 4MB pages. 
        mov cr4, ecx 

        mov ecx, cr0 
        or ecx, 0x80000000       ; Set PG bit in CR0 to enable paging. 
        mov cr0, ecx 


        lea ebx, [higherhalf] 
        jmp ebx 

     higherhalf: 
       ; Unmap the identity-mapped first 4MB of physical address space. It should not be needed 
       ; anymore. 
       mov dword [BootPageDirectory], 0 
       invlpg [0] 

       mov esp, stack   ; set up the stack 
       call callConstructors 

       push eax 
       push ebx 
       call kernelMain 
       jmp _eof 

     _eof: 
      cli 
      hlt 
      jmp _eof 


section .bss 
align 32 
stack: 
    resb STACKSIZE  ; reserve 16k stack on a uint64_t boundary 

这里是我的操作系统我的全部源代码:https://github.com/amanuel2/OS_MIRROR。帮助将不胜感激。

+2

完全与您的问题无关。但我注意到你做了'mov esp,stack'。所以ESP将会从标签'堆栈'变小。但是你用'stack'定义'stack': resb STACKSIZE'。问题在于堆栈会在标签堆栈之前进入内存。您应该在'resb STACKSIZE'之后放置一个标签,并将其用作堆栈的顶部。 –

+0

@MichaelPetch所以mov esp,stack + STACKSIZE? – amanuel2

+0

在这种情况下就足够了。 –

回答

0

什么解决的,这是当我摆脱了EQU语句,并从入口声明刚刚开始:

;Global MultiBoot Kernel Recongnzation 
    MAGIC equ 0x1badb002 
    FLAGS equ (1<<0 | 1<<1) 
    CHECKSUM equ -(MAGIC + FLAGS) 


    ;Putting in object file 
    section .multiboot 
     dd MAGIC 
     dd FLAGS 
     dd CHECKSUM 

    section .data 

    KERNEL_VIRTUAL_BASE equ 0xC0000000     ; 3GB 
    KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; Page directory index of kernel's 4MB PTE. 

    align 0x1000 
    BootPageDirectory: 
     ; This page directory entry identity-maps the first 4MB of the 32-bit physical address space. 
     ; All bits are clear except the following: 
     ; bit 7: PS The kernel page is 4MB. 
     ; bit 1: RW The kernel page is read/write. 
     ; bit 0: P The kernel page is present. 
     ; This entry must be here -- otherwise the kernel will crash immediately after paging is 
     ; enabled because it can't fetch the next instruction! It's ok to unmap this page later. 
     dd 0x00000083 
     times (KERNEL_PAGE_NUMBER - 1) dd 0     ; Pages before kernel space. 
     ; This page directory entry defines a 4MB page containing the kernel. 
     dd 0x00000083 
     times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0 ; Pages after the kernel image. 


    section .text 
     extern kernelMain 
     extern callConstructors 
     extern page_directory 
     extern pages_init 
     ; reserve initial kernel stack space -- that's 16k. 
     STACKSIZE equ 0x4000 
     ; setting up entry point for linker 
     loader equ (_loader - 0xC0000000) 
     global loader 

     _loader: 
        ;Enable Paging START 

        ; NOTE: Until paging is set up, the code must be position-independent and use physical 
        ; addresses, not virtual ones! 
        mov ecx, (BootPageDirectory - KERNEL_VIRTUAL_BASE) 
        mov cr3, ecx          ; Load Page Directory Base Register. 

        mov ecx, cr4 
        or ecx, 0x00000010       ; Set PSE bit in CR4 to enable 4MB pages. 
        mov cr4, ecx 

        mov ecx, cr0 
        or ecx, 0x80000000       ; Set PG bit in CR0 to enable paging. 
        mov cr0, ecx 


        lea ebx, [higherhalf] 
        jmp ebx 

     higherhalf: 
       ; Unmap the identity-mapped first 4MB of physical address space. It should not be needed 
       ; anymore. 
       mov dword [BootPageDirectory], 0 
       invlpg [0] 

       mov esp, stack   ; set up the stack 
       call callConstructors 

       push eax 
       push ebx 
       call kernelMain 
       jmp _eof 

     _eof: 
      cli 
      hlt 
      jmp _eof 


section .bss 
align 32 
stack: 
    resb STACKSIZE  ; reserve 16k stack on a uint64_t boundary 

得到了OsDev维基此帮助:http://f.osdev.org/viewtopic.php?f=1&t=28796

+0

您发布的代码与第一个版本相同,但第二个代码中有额外的选项卡和空格。代码本身并没有什么不同。 –