1 year ago

#364062

test-img

Teer 2008

Qemu can't boot custom operating system

I followed wiki.osdev.org's bare-bones tutorial and wrote a kernel.c, boot.s and linker.ld file. To speed up the compilation process, I wrote another shell script:

i686-elf-as boot/boot.s -o boot/boot.o
i686-elf-gcc -c kernel/kernel.c -o kernel/kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-elf-gcc -T boot/linker.ld -o boot/myos.bin -ffreestanding -O2 -nostdlib boot/boot.o kernel/kernel.o -lgcc

mkdir -p isodir/boot/grub
cp myos.bin isodir/boot/myos.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o myos.iso isodir

qemu-system-i386 -cdrom myos.iso

The problem seems simple, because Qemu just shows "No bootable device" I thought that Qemu just can't find the file, but that's not the problem. I even rewrote the entire code.

Kernel file:

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#if defined(__linux__)
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif

#if !defined(__i386__)
#error "This needs to be compiled with a ix86-elf compiler"
#endif

enum vga_color {
        VGA_COLOR_BLACK = 0,
        VGA_COLOR_BLUE = 1,
        VGA_COLOR_GREEN = 2,
        VGA_COLOR_CYAN = 3,
        VGA_COLOR_RED = 4,
        VGA_COLOR_MAGENTA = 5,
        VGA_COLOR_BROWN = 6,
        VGA_COLOR_LIGHT_GREY = 7,
        VGA_COLOR_DARK_GREY = 8,
        VGA_COLOR_LIGHT_BLUE = 9,
        VGA_COLOR_LIGHT_GREEN = 10,
        VGA_COLOR_LIGHT_CYAN = 11,
        VGA_COLOR_LIGHT_RED = 12,
        VGA_COLOR_LIGHT_MAGENTA = 13,
        VGA_COLOR_LIGHT_BROWN = 14,
        VGA_COLOR_WHITE = 15,
};

static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
{
        return fg | bg << 4;
}

static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
{
        return (uint16_t) uc | (uint16_t) color << 8;
}

size_t strlen(const char* str)
{
        size_t len = 0;
        while (str[len])
                len++;
        return len;
}

static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;

size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;

void terminal_initialize(void)
{
        terminal_row = 0;
        terminal_column = 0;
        terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
        terminal_buffer = (uint16_t*) 0xB8000;
        for (size_t y = 0; y < VGA_HEIGHT; y++) {
                for (size_t x = 0; x < VGA_WIDTH; x++) {
                        const size_t index = y * VGA_WIDTH + x;
                        terminal_buffer[index] = vga_entry(' ', terminal_color);
                }
        }
}

void terminal_setcolor(uint8_t color)
{
        terminal_color = color;
}

void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
{
        const size_t index = y * VGA_WIDTH + x;
        terminal_buffer[index] = vga_entry(c, color);
}

void terminal_putchar(char c)
{
        terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
        if (++terminal_column == VGA_WIDTH) {
                terminal_column = 0;
                if (++terminal_row == VGA_HEIGHT)
                        terminal_row = 0;
        }
}

void terminal_write(const char* data, size_t size)
{
        for (size_t i = 0; i < size; i++)
                terminal_putchar(data[i]);
}

void terminal_writestring(const char* data)
{
        terminal_write(data, strlen(data));
}

void kernel_main(void)
{
        /* Initialize terminal interface */
        terminal_initialize();

        /* Newline support is left as an exercise. */
        terminal_writestring("Hello, kernel World!\n");
}

Boot file:

.set ALIGN,    1<<0
.set MEMINFO,  1<<1
.set FLAGS,    ALIGN | MEMINFO
.set MAGIC,    0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)

.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM

.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:

.section .text
.global _start
.type _start, @function
_start:
        mov $stack_top, %esp
        call kernel_main
        cli
1:      hlt
        jmp 1b

.size _start, . - _start

Linker file:

ENTRY(_start)

SECTIONS
{
        . = 1M;

        .text BLOCK(4K) : ALIGN(4K)
        {
                *(.multiboot)
                *(.text)
        }


        .rodata BLOCK(4K) : ALIGN(4K)
        {
                *(.rodata)
        }


        .data BLOCK(4K) : ALIGN(4K)
        {
                *(.data)
        }


        .bss BLOCK(4K) : ALIGN(4K)
        {
                *(COMMON)
                *(.bss)
        }

}

c

operating-system

osdev

0 Answers

Your Answer

Accepted video resources