首页 文章

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

提问于
浏览
1

我一直在开发一个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 回答

  • 4

    你说Stage2是在段 0x0200 加载的,它是地址 0x2000 ,但你的链接器说它从offset 0x0200 开始 .

    此外,尽管命名输出“Anmu . bin ”,但您的文件实际上仍然是ELF可执行文件,这意味着文件中仍然存在所有 Headers 和诸如此类的文件 . 相反,您需要使用objcopy去除所有 Headers 和调试符号,为您提供一个平面二进制文件:

    objcopy -S -O binary Anmu.bin Anmu-flat.bin
    

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

相关问题