2013-01-14 57 views
23

में बूट नहीं होगा मैं OSDev.org से कुछ ओएस विकास सीख रहा हूं। मेरे पास एक कर्नेल है और मैं qemu का उपयोग कर GRUB विरासत (0.97) में बूट करने की कोशिश कर रहा हूं। हालांकि, जब मैं kernel 200+9 टाइप करें, मैं संदेशसरल कर्नेल GRUB

[Multiboot-elf, <0x100000:0x80:0x4008>(bad), entry=0x10000c] 

मिल यह मैं (बुरा) भाग के अलावा क्या उम्मीद है। अगर मैं boot टाइप करता हूं तो अब GRUB बस लटकता है।

मुझे लगता है कि .text सेगमेंट के लिए संख्या 0x100000, 0x44, 0x4008 स्टैंड पता, .bss प्रारंभ पता, और .bss अनुभाग आकार क्रमशः। मैं इस बारे में सोच क्योंकि गिरी छवि पर objdump -h चल रहा यह उत्पादन देता है:

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 

तो आप देख सकते है कि संख्या मैं लगभग मेल उल्लेख। मुद्दा यह है कि 100044 की बजाय, .bss की शुरुआत सिर्फ 44 है। और मुझे लगता है कि यही कारण है कि GRUB खराब कह रहा है। मेरे पास मेमोरी (कम मेमोरी) में 1 एमबी से नीचे कोई अनुभाग नहीं हो सकता है। लेकिन objdump मुझे बता रहा है कि मेरे वर्ग उस दहलीज से ऊपर हैं, इसलिए मुझे नहीं पता कि क्या गलत है। वैसे भी, मैं नीचे अपना कोड पेस्ट कर दूंगा, यह अपेक्षाकृत छोटा है। यद्यपि मेरा प्रश्न शायद मूलभूत है यदि आपने पहले ओएस देव किया है, तो कोड अपर्याप्त हो सकता है।

;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 

कहाँ Stage1 और stage2 GRUB Legacy से फाइल कर रहे हैं और

// 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; 
} 

नीचे अपने कस्टम लिंकर स्क्रिप्ट है पैड कोई 750 बाइट फ़ाइल है (इसलिए चरण 1 + चरण 2 + पैड में 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 –

उत्तर

22

सभी विवरण के साथ अच्छा प्रश्न के लिए +1, धन्यवाद।

कम से कम मेरी मशीन पर उत्पन्न kernel.bin 4869 बाइट्स है, जो केवल 10 क्षेत्रों में फिट बैठता है के रूप में बाहर आता है नहीं 9. इसके अलावा, वीजीए पाठ स्मृति है 0xb8000 नहीं 0xb800 (एक और शून्य पर - 0xb800 वास्तविक मोड खंड है, 16 से गुणा किया जाना है)। उन छोटे समायोजनों के साथ यह ठीक काम करता है।

+0

वाह, मुद्दा 0xb800 साथ था ... मैंने सोचा कि यह लटक रहा था लेकिन यह वास्तव में चरित्र को स्मृति में सही स्थान पर नहीं डाल रहा था ... हालांकि मैं अभी भी इसके बारे में उलझन में हूं: '<0x100000: 0x80: 0x4008> (खराब)', क्योंकि आपको नहीं होना चाहिए कम मेमोरी में सेगमेंट रखने की इजाजत है (अगर मैंने सही संख्याओं का अर्थ व्याख्या किया है) ... – gsingh2011

+0

और दूसरों के लिए थोड़ा सा स्पष्टीकरण देने के लिए, यह अभी भी बूट (भले ही) कहता है। – gsingh2011

+2

यह कहता है कि '(खराब)' यदि आप पर्याप्त क्षेत्रों को लोड नहीं करते हैं। यह अभी भी काम कर सकता है अगर उस हिस्से में कुछ भी महत्वपूर्ण नहीं रहता है। क्या आपने '200 + 10' के साथ प्रयास किया है? – Jester