我一直在开发一个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
答案 0 :(得分:4)
你说Stage2是在段 0x0200
加载的,它是地址0x2000
,但你的链接器说它从 offset {{开始1}}。
此外,尽管命名输出" Anmu。 bin ",您的文件实际上仍然是ELF可执行文件,这意味着所有标题和诸如此类的东西仍然存在于文件。相反,您需要使用objcopy
去除所有标题和调试符号,为您提供平面二进制文件:
0x0200
现在," Anmu-flat.bin"只不过是代码和数据,文件的第一个字节是第一条指令的开头。