Error 13: Ungültige oder nicht unterstützte ausführbare Datei beim Booten des einfachen Kernels in Grub mit String-Literal

Ich habe einen einfachen Kernel geschrieben, der versucht, zwei Zeichen in den Bildspeicher zu schreiben.

Wenn ich ein String-Literal im Kernel definiere, erhalte ich beim Booten die folgende Ausgabe:

  Booting 'os'                                                                  

kernel /boot/kernel.elf                                                         

Error 13: Invalid or unsupported executable format                              

Press any key to continue... 

Andernfalls erhalte ich, wenn ich zwei Zeichen definiere, Folgendes (Anmerkung 'ab' am Anfang der Ausgabe):

abBooting 'os'                                                                  

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

Ich habe den Loader in der Assembly geschrieben:

global loader                   ; the entry symbol for ELF

MAGIC_NUMBER equ 0x1BADB002     ; define the magic number constant
FLAGS        equ 0x0            ; multiboot flags
CHECKSUM     equ -MAGIC_NUMBER  ; calculate the checksum
                                ; (magic number + checksum + flags should equal 0)
KERNEL_STACK_SIZE equ 4096      ; size of stack in bytes

section .text:                  ; start of the text (code) section
align 4                         ; the code must be 4 byte aligned
    dd MAGIC_NUMBER             ; write the magic number to the machine code,
    dd FLAGS                    ; the flags,
    dd CHECKSUM                 ; and the checksum

loader:                         ; the loader label (defined as entry point in linker script)
    mov eax, 0xCAFEBABE         ; place the number 0xCAFEBABE in the register eax

    mov esp, kernel_stack + KERNEL_STACK_SIZE   ; point esp to the start of the
                                                ; stack (end of memory area)
    extern run  
    call run

.loop:
    jmp .loop                   ; loop forever

section .bss
align 4                         ; align at 4 bytes
kernel_stack:                   ; label points to beginning of memory
    resb KERNEL_STACK_SIZE          ; reserve stack for the kernel
Der Kernel ist in c @ geschrieb
#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
}
Externe Header

Es gibt zwei externe Header. Einer für IO-Ports mit dem Namen io.h und einer zum Schreiben in den Frame-Puffer mit dem Namen fb.h

Hier ist io.h und die Implementierung io.s

io.h:

#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);

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;

}
Building it

Ich habe ein Linker-Skript namens link.ld und ein Makefile. Ich verwende den GCC-Cross-Compiler für i386-elf, den ich mithilfe dieses Handbuchs kompiliert habe http: //wiki.osdev.org/GCC_Cross-Compile).

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 = .;


    }
}

Und hier ist mein Makefile

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)  
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 $@

%.o: %.s
    $(AS) $(ASFLAGS) $< -o $@

clean:
    rm -rf *.o kernel.elf os.iso
lt; -o $@ %.o: %.s $(AS) $(ASFLAGS)
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 $@

%.o: %.s
    $(AS) $(ASFLAGS) $< -o $@

clean:
    rm -rf *.o kernel.elf os.iso
lt; -o $@ clean: rm -rf *.o kernel.elf os.iso
Starte e

Das Makefile erstellt eine ISO aus dem Inhalt eines Verzeichnisses namens ISO. Dieser Ordner enthält eine vorkonfigurierte Version von grub, die ich hier bekommen habe https: //github.com/littleosbook/littleosbook/blob/master/files/stage2_eltorit) und eine menu.lst-Datei für grub

menu.lst:

default=0
timeout=0

title os
kernel /boot/kernel.elf

contents of iso directory:

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

The ISO-Image lädt in bochs auf. Hier ist meine bochsrc.txt Datei

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

Weiß jemand, warum das String-Literal in der Kernel-Datei den Fehler erzeugt, wenn ich versuche, die ISO zu booten?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage