저는 약간의 OS 개발을 OSDev.org에서 배우고 있습니다. 커널이 있고 qemu를 사용하여 GRUB Legacy (0.97)에서 부팅하려고합니다. 내가 kernel 200+9
를 입력 할 때 그러나, 나는이 내가 (나쁜) 부분을 제외하고 기대되는 메시지간단한 커널이 GRUB에서 부팅되지 않습니다
[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c]
를 얻을. 지금 입력하면 boot
GRUB 그냥 중단됩니다.
숫자는 0x100000, 0x44, 0x4008은 .text 세그먼트 시작 주소, .bss 시작 주소 및 .bss 섹션 크기를 각각 의미합니다.
kernel.bin: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000044 00100000 00100000 00001000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00004008 00100044 00100044 00001044 2**2
ALLOC
그래서 당신이 숫자는 내가 일치 거의 언급 한 것을 볼 수 있습니다 : 커널 이미지에
objdump -h
를 실행하면이 출력을 제공하기 때문에 나는이 생각합니다. 문제는 100044 대신에 .bss의 시작이 44입니다. 그리고 이것이 GRUB이 나쁜 것을 말하는 이유라고 생각합니다. 1MB 미만의 섹션 (메모리 부족)을 가질 수 없습니다. 그러나 objdump는 내 섹션이 임계 값보다 높다는 것을 알려주므로 잘못된 점을 알지 못합니다. 어쨌든 아래 코드를 붙여 놓을 테니 비교적 짧습니다. 이전에 OS dev을 해본 적이 있다면 제 질문은 아마도 매우 기본적인 것이지만, 코드는 쓸데없는 것일 수 있습니다.
;loader.s - contains the multiboot header for grub and calls the main kernel method
global loader ; making entry point visible to linker
global magic ; we will use this in kmain
global mbd ; we will use this in kmain
extern kmain ; kmain is defined in kmain.cpp
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ 0x03;MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
loader:
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
mov esp, stack + STACKSIZE ; set up the stack
mov [magic], eax ; Multiboot magic number
mov [mbd], ebx ; Multiboot info structure
call kmain ; call kernel proper
cli
.hang:
hlt ; halt machine should kernel return
jmp .hang
section .bss
align 4
stack: resb STACKSIZE ; reserve 16k stack on a doubleword boundary
magic: resd 1
mbd: resd 1
.
ENTRY (loader)
SECTIONS {
. = 0x00100000;
.text ALIGN (0x1000) : {
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata*)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
/DISCARD/ : {
*(.eh_frame)
*(.comment)
}
}
그리고 마지막으로, 나는 다음과 같은 라인 커널 구축 :
nasm -f elf -o loader.o loader.s
gcc -c -o kernel.o kernel.c
ld -T linker.ld -o kernel.bin loader.o kernel.o
cat stage1 stage2 pad kernel.bin > floppy.img
스테이지 1과 스테이지 2는 GRUB 레거시에서 파일입니다
및 아래
// kernel.c - Contains the main kernel method
void kmain() {
extern unsigned int magic;
if (magic != 0x2BADB002) {
// Something went wrong
}
volatile unsigned char *videoram = (unsigned char *) 0xB800;
videoram[0] = 65;
videoram[1] = 0x07;
}
내 사용자 정의 링커 스크립트입니다 pad는 750 바이트 파일입니다 (따라서 stage1 + stage2 + 패드의 파일 크기는 102400 바이트 또는 200 블록이므로 커널 200 + 9로 부팅하는 이유입니다).
마지막으로, 나는 QEMU의 커널을 실행 : 모든 세부 사항 좋은 질문에 대한
qemu-system-x86_64 -fda floppy.img
리포지토리 : https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/osdev 와우,이 문제는 0xb800로했다 ... 나는 그것이 걸려라고 생각 –