Я разрабатывал Bootloader и столкнулся с проблемой при связывании кода c ++ с моим кодом ассемблера stage2, прежде чем я связывал файлы. Второй этап без проблем перешел бы в защищенный режим, затем в длинный режим, но теперь, после того как я связал его, кажется, быть проблемой при переходе в защищенный режим Вот код, который я использую для перехода в защищенный режим:
main:
;first stage of bootloader is loaded at the address 0x07c0:0
;second stage of bootloader is loaded at address 0x200:0x0cli
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 EnableA20mov 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
Вы говорите, что Stage2 загружен в сегмент 0x0200
по адресу 0x2000
, но ваш компоновщик говорит, что начинается в смещение 0x0200
,
Кроме того, несмотря на название вашего выхода «Анму.бункер«, ваш файл на самом деле все еще исполняемый файл ELF, что означает, что все заголовки и тому подобное все еще присутствуют в файле. Вместо этого вам нужно использовать objcopy
убрать все заголовки и символы отладки, давая вам плоский двоичный файл:
objcopy -S -O binary Anmu.bin Anmu-flat.bin
Теперь «Anmu-flat.bin» — это не что иное, как код и данные, и первый байт файла является началом первой инструкции.