链接内核后跳转到保护模式不起作用

时间:2014-08-12 19:02:23

标签: c++ assembly x86 nasm osdev

我一直在开发一个Bootloader并且在将c ++代码链接到我的程序集stage2代码之前遇到了问题我链接文件之前第二阶段会跳转到保护模式然后转到长模式而没有任何问题但现在我已经链接跳转到保护模式时似乎有问题以下是我用来跳转到保护模式的代码:

main:            
;first stage of bootloader is loaded at the address 0x07c0:0 
        ;second stage of bootloader is loaded at address 0x200:0x0 


        cli 
   xor ax, ax         ; All segments set to 0, flat memory model 
   mov ds, ax 
   mov es, ax 
   mov gs, ax 
   mov fs, ax 
   mov ss, ax 
   ; 
   ; Set stack top SS:0xffff 
   ; 
   mov sp, 0x0FFFF 
   ; 


        mov [CDDriveNumber], dl 

        SwitchToProtectedMode: 
        lgdt [GDT_32];load the gdt 

        call EnableA20 



        mov eax, cr0 
        or eax, 1 
        mov cr0, eax 


        ; Flush CS and set code selector 
        ;   

        jmp 0x8:Protected_Mode 

        [BITS 32];Declare 32 bits 

        Protected_Mode: 

这是GDT:

GDT_START: 
;null descriptor 
dd 0 
dd 0 
;data descriptor 
dw 0xFFFF 
dw 0 
db 0 
db 10011010b 
db 11001111b 
db 0 
;code descriptor 
dw 0xFFFF 
dw 0 
db 0 
db 10010010b 
db 11001111b 
db 0 
GDT_END: 
align 4 
GDT_32: 
dw GDT_END - GDT_START - 1 
dd GDT_START

这是我用来链接我的c和汇编代码

的链接描述文件
KernAddr = 0x200;
ENTRY(_Start)
SECTIONS
{
    . = KernAddr;

    .text : AT(ADDR(.text) - KernAddr)
    {
        _code = .;
        *(.text)
        *(.rodata*)
        . = ALIGN(4096);
    }

   .data : AT(ADDR(.data) - KernAddr)
   {
        _data = .;
        *(.data)
        . = ALIGN(4096);
   }

   .eh_frame : AT(ADDR(.eh_frame) - KernAddr)
   {
       _ehframe = .;
       *(.eh_frame)
        . = ALIGN(4096);
   }

   .bss : AT(ADDR(.bss) - KernAddr)
   {
       _bss = .;
       *(.bss)

       /*
        * You usually need to include generated COMMON symbols
        * under kernel BSS section or use gcc's -fno-common
        */

        *(COMMON)
       . = ALIGN(4096);
   }

   _end = .;

   /DISCARD/ :
   {
        *(.comment)
   }
}

这是我为构建所有内容而制作的批处理程序:

nasm Stage1.asm -o Stage1.bin
nasm -f elf64 Stage2.asm -o Stage2.o
x86_64-elf-g++ -ffreestanding -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -c -o kernel.o kernel.cpp
x86_64-elf-ld -T linkerscript.ld -o Anmu.bin Stage2.o kernel.o -nostdlib
copy Stage1.bin Root
copy Anmu.bin Root
mkisofs -b Stage1.bin -no-emul-boot -boot-info-table -o BootLoader.iso ./Root

其余代码可在此处找到:https://github.com/AnonymousUser1337/Anmu

1 个答案:

答案 0 :(得分:4)

你说Stage2是在 0x0200加载的,它是地址0x2000,但你的链接器说它从 offset {{开始1}}。

此外,尽管命名输出" Anmu。 bin ",您的文件实际上仍然是ELF可执行文件,这意味着所有标题和诸如此类的东西仍然存在于文件。相反,您需要使用objcopy去除所有标题和调试符号,为您提供平面二进制文件:

0x0200

现在," Anmu-flat.bin"只不过是代码和数据,文件的第一个字节是第一条指令的开头。