跳转到保护模式连接内核后不工作 [英] Jump to Protected Mode not working after linking the kernel

查看:195
本文介绍了跳转到保护模式连接内核后不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发一个引导程序和链接C ++ code时,我的组装阶段2 code之前,我联系了第二阶段将跳转到保护模式,然后以长模式​​的文件,没有任何问题,遇到了一个问题但现在我已经联系在一起后,似乎有一个问题跳转到保护模式时,这里是code我用跳转到保护模式:

I have been developing a Bootloader and have run into a problem when linking c++ code to my assembly stage2 code before I linked the files the second stage would jump to protected mode then to long mode without any problems but now after I have linked it there seems to be a problem when jumping to protected mode Here is the code I use to jump to protected mode:

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语言和汇编code中的链接脚本

Here is the linker script I use to link my c and assembly code

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)
   }
}

下面是我做出的一切建立批处理程序:

Here is the batch program I made to build everything:

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

在code的其余部分可以在这里找到: https://github.com/AnonymousUser1337/Anmu

推荐答案

您说,2阶段在加载的 0x0200 ,这是地址为0x2000 ,但你的链接表示,在开始的偏移 0x0200

You say that Stage2 is loaded at segment 0x0200, which is address 0x2000, but your linker says it starts at offset 0x0200.

此外,尽管命名你的输出​​安牧。,你的文件实际上仍然是一个ELF可执行文件,这意味着所有的头和诸如此类的东西仍在present的文件中。相反,你需要使用 objcopy把 ,以去除所有页眉和调试符号,给你一个平坦的二进制文件:

Also, despite naming your output "Anmu.bin", your file is actually still an ELF executable, which means all of the headers and whatnot are still present in the file. Instead, you need to use objcopy to strip all of the headers and debugging symbols, giving you a flat binary:

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

现在,安牧-flat.bin只不过是code和数据,并且该文件的第一个字节是第一指令的起始

Now, "Anmu-flat.bin" is nothing but code and data, and the first byte of the file is the start of the first instruction.

这篇关于跳转到保护模式连接内核后不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆