2015-02-25 13 views
5

Çerçeve arabelleğine iki karakter yazmayı deneyen basit bir çekirdek yazdım.Hata 13: Basit veya desteklenmeyen yürütülebilir dosya dizgisi dizgisi ile basit çekirdeği önyüklenirken

Booting 'os'                 

kernel /boot/kernel.elf               

Error 13: Invalid or unsupported executable format        

Press any key to continue... 

Aksi takdirde başında ben 'ab' notu (şu olsun iki karakter tanımlarsanız,: ı çekirdekte değişmez bir dize tanımlarsanız o çizme zaman

, aşağıdaki çıktıyı almak çıktı):

:

abBooting 'os'                 

kernel /boot/kernel.elf              
    [Multiboot-elf, <0x100000:0x201:0x0>, <0x101000:0x0:0x1000>,  shtab=0x102168, 
    entry=0x1001f0] 

yükleyici

Ben mecliste yükleyici yazdı

çekirdek c

#include "io.h" 
#include "fb.h" 

void run() 
{ 
    // try writing message to port 
    char* c = (char *) 10000; 
    c[0] = 'a'; 
    c[1] = 'b'; 

    fb_write(c, 2); // this does not cause the error 

    // fb_write("ab",2); // this line would cause the error 
} 

Dış başlıklarını

iki harici başlıkları bulunmaktadır yazılır. İşte

fb.h denilen çerçeve tampon yazdığın için io.h denilen IO portlar için bir ve tek io.h ve uygulama

io.h io.s:

#ifndef INCLUDE_IO_H 
#define INCLUDE_IO_H 

/** outb: 
* Sends the given data to the given I/O port. Defined in io.s 
* 
* @param port The I/O port to send the data to 
* @param data The data to send to the I/O port 
*/ 
void outb(unsigned short port, unsigned char data); 

#endif /* INCLUDE_IO_H */ 

io.s:

global outb  ; make the label outb visible outside this file 

; outb - send a byte to an I/O port 
; stack: [esp + 8] the data byte 
;  [esp + 4] the I/O port 
;  [esp ] return address 
outb: 
    mov al, [esp + 8] 
    mov dx, [esp + 4] 
    out dx, al 
    ret 

fb.h

#include "io.h" 

// FRAME BUFFER ================================ 

// Text colors 
#define FB_BLACK  0 
#define FB_BLUE   1 
#define FB_GREEN  2 
#define FB_CYAN   3 
#define FB_RED   4 
#define FB_MAGENTA  5 
#define FB_BROWN  6 
#define FB_LT_GREY  7 
#define FB_DARK_GREY 8 
#define FB_LT_BLUE  9 
#define FB_LT_GREEN 10 
#define FB_LT_CYAN  11 
#define FB_LT_RED  12 
#define FB_LT_MAGENTA 13 
#define FB_LT_BROWN 14 
#define FB_WHITE  15 

// IO PORTS 
#define FB_COMMAND_PORT 0x3D4 
#define FB_DATA_PORT 0x3D5 

// IO PORT COMMANDS 
#define FB_HIGH_BYTE_COMMAND 14 // move cursor command low 
#define FB_LOW_BYTE_COMMAND  15 // move cursor command high 


/** fb_write_cell: 
* used to write a character to a cell in the framebuffer 
* 
* param i which cell to write to 
* param c the ascii char to write 
* param fg foreground color 
* param bf background color 
*/ 
void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned char bg); 


/** fb_move_cursor: 
* used to move the cursor within the frame buffer 
* 
* param pos position within frame buffer to move cursor to 
*/ 
void fb_move_cursor(unsigned short pos); 


/** fb_write: 
* write some text to the cursor 
* 
* param buf pointer to character string 
* param len length of string to write 
*/ 
int fb_write(char *buf, unsigned int len); 
Bunu

Bina 0

fb.c

#include "fb.h" 

void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned char bg) 
{ 
    char *fb = (char *) 0x000B8000; 
    fb[i*2] = c; 
    fb[i*2 + 1] = ((fg & 0x0F) << 4) | (bg & 0x0F); 
} 

void fb_move_cursor(unsigned short pos) { 
    outb(FB_COMMAND_PORT, FB_HIGH_BYTE_COMMAND); 
    outb(FB_DATA_PORT, ((pos>>8) & 0x00FF)); 
    outb(FB_COMMAND_PORT, FB_LOW_BYTE_COMMAND); 
    outb(FB_DATA_PORT, pos & 0x00FF); 
} 

int fb_write(char *buf, unsigned int len) { 

    unsigned int i = 0; 
    for(i = 0; i < len; i++) { 
     fb_write_cell(i, buf[i], FB_BLACK, FB_WHITE); 
    } 

    return 0; 

} 

Bir bağlayıcı komut adı verilen link.ld ve bir Makefile var. Bu kılavuzu kullanarak derlediğim i386-elf için gcc cross derleyicisi kullanıyorum (http://wiki.osdev.org/GCC_Cross-Compiler).

ENTRY(loader)    /* the name of the entry label */ 

SECTIONS { 
    . = 0x00100000;   /* the code should be loaded at 1 MB */ 

    .text ALIGN (0x1000) : /* align at 4 KB */ 
    { 
     *(.text)    /* all text sections from all files */ 
    } 

    .rodata ALIGN (0x1000) : /* align at 4 KB */ 
    { 
     *(.rodata*)   /* all read-only data sections from all files */ 
    } 

    .data ALIGN (0x1000) : /* align at 4 KB */ 
    { 
     *(.data)    /* all data sections from all files */ 
    } 

    .bss ALIGN (0x1000) : /* align at 4 KB */ 
    { 
     sbss = .; 
     *(COMMON)   /* all COMMON sections from all files */ 
     *(.bss)    /* all bss sections from all files */ 
     ebss = .; 


    } 
} 

Ve işte

makefile bir dizin olarak adlandırılan iso içeriğinden bir iso oluşturur

OBJECTS = io.o fb.o loader.o kmain.o 
#CC = gcc 
CC = /home/albertlockett/opt/cross/bin/i386-elf-gcc 
CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \ 
     -nostartfiles -nodefaultlibs -Wall -Wextra -Werror -c 
LDFLAGS = -T link.ld -melf_i386 
AS = nasm 
ASFLAGS = -f elf 

all: kernel.elf 

kernel.elf: $(OBJECTS) 
    ld $(LDFLAGS) $(OBJECTS) -o kernel.elf 

os.iso: kernel.elf 
    cp kernel.elf iso/boot/kernel.elf 
    genisoimage -R        \ 
       -b boot/grub/stage2_eltorito \ 
       -no-emul-boot     \ 
       -boot-load-size 4    \ 
       -A os       \ 
       -input-charset utf8    \ 
       -quiet       \ 
       -boot-info-table    \ 
       -o os.iso      \ 
       iso 

run: os.iso 
    bochs -f bochsrc.txt -q 

%.o: %.c 
    $(CC) $(CFLAGS) $< -o [email protected] 

%.o: %.s 
    $(AS) $(ASFLAGS) $< -o [email protected] 

clean: 
    rm -rf *.o kernel.elf os.iso 

Run benim Makefile olduğunu. Yani klasör burada (https://github.com/littleosbook/littleosbook/blob/master/files/stage2_eltorito) var grub önceden yapılandırılmış bir versiyonunu ve grub için bir menu.lst'in dosyasını içeren

menu.lst'in: iso dizinin

default=0 
timeout=0 

title os 
kernel /boot/kernel.elf 

içeriği:

iso 
`-- boot 
    |-- grub 
    | |-- menu.lst 
    | `-- stage2_eltorito 
    `-- kernel.elf 

Iso görüntüsü botlarda botlar. İşte benim bochsrc.txt dosyası

megs:   32 
display_library: term 
romimage:  file=/usr/share/bochs/BIOS-bochs-latest 
vgaromimage:  file=/usr/share/bochs/VGABIOS-lgpl-latest 
ata0-master:  type=cdrom, path=os.iso, status=inserted 
boot:   cdrom 
log:    bochslog.txt 
clock:   sync=realtime, time0=local 
cpu:    count=1, ips=1000000 
com1:   enabled=1, mode=file, dev=com1.out 
ben iso önyükleme yapmaya çalıştığınızda çekirdek dosyasında değişmez dize hata üretir neden

bilen var mı?

+0

Wow, gerçekten benimle aynı sorunu olan birisinin beklemesini beklemiyordum – cstack

+0

Bu da vardı ... .xtxt kolonunun littleosbook'un kendisinde bir yazım hatası olduğunu. – cmlaverdiere

cevap

6

section .text:'un sonunda ek bir kolonunuz var, bu da .text: adında yeni bir bölüm oluşturur. Belgelerdeki hızlı bir bakıştan öğrenemediğim bazı belirsiz nedenlerden dolayı, linker betiğinizde listelenmemiş olsa bile bu bölüm çıktıya gönderilir. C kodunda herhangi bir değişmez veri bulunmadığında, görüntünün ilk 8kiB'inde düştüğünden ve böylece çoklu çizgi üstbilgisinin gerekli kısımda olduğundan şanslısınız demektir. Bir dize değişkeni varsa, .rodata yeni bir bölüm alırsınız ve bu, henüz bir başka belirsiz nedenden dolayı, .text:'dan önce ancak standart .text'dan sonra sıralanır. Örnek:

Sections: 
Idx Name   Size  VMA  LMA  File off Algn 
    0 .text   00000001 00100000 00100000 00001000 2**4 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
    1 .rodata  00000005 00101000 00101000 00002000 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    2 .text:  00000018 00101008 00101008 00002008 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    3 .bss   0000100a 00102000 00102000 00003000 2**2 
        ALLOC 

Eğer grub çok üzücü olacak bu yüzden, artık görüntünün ilk 8kiB içinde var görebileceğiniz gibi.

TL; DR: section .text:'dan sonra ek kolonları kaldırın.

+0

Teşekkürler! Bu düzeltildi. Bu çıkışı nasıl ürettin? – albertlockett

+0

Kullanılan 'objdump -h' – Jester

+0

Neden kolon başka bir bölüm oluşturuyor? – cstack