2013-01-14 5 views
23

저는 약간의 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 
+0

리포지토리 : https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/osdev 와우,이 문제는 0xb800로했다 ... 나는 그것이 걸려라고 생각 –

답변

22

+1, 감사합니다. , 0xb800 리얼 모드 세그먼트 -

는 적어도 내 컴퓨터에서 생성 된 kernel.bin하지 9. 0xb8000하지 0xb800 (또 하나의 제로 또한, VGA 텍스트 메모리에만 10 개 부문에서 맞는 4869 바이트로 나온다 16을 곱해야한다). 작은 조정으로 여기에서 잘 작동합니다. 그 예를 들어 작업에

+0

하지만 실제로 메모리에서 올바른 위치에 캐릭터를 배치하지는 않았습니다. 다음과 같은 내용에 대해 아직도 혼란 스럽지만 : <0x100000 : 0x80 : 0x4008> (나쁜)' (숫자의 의미를 정확하게 해석한다면) 낮은 메모리에 세그먼트를 가질 수 있습니다 ... – gsingh2011

+0

그리고 다른 사람들을 약간 명확히하기 위해, (나쁜) 말로도 여전히 부팅합니다. – gsingh2011

+2

충분한 섹터를로드하지 않으면'(불량) '이라고 표시됩니다. 중요한 부분이 없으면 작동 할 수 있습니다. '200 + 10' 시도해 봤어? – Jester