Add Multiboot 2 i386 kernel example

This commit is contained in:
Alex Kotov 2022-01-09 08:06:03 +05:00
parent 3b7ceeb201
commit 7bd6ee7d2a
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
6 changed files with 172 additions and 0 deletions

View File

@ -0,0 +1,2 @@
/image.iso
/rootfs/boot/kernel

View File

@ -0,0 +1,44 @@
CCPREFIX = i386-elftailix-
AS = $(CCPREFIX)as
CC = $(CCPREFIX)gcc
IMAGE = image.iso
LINKERSCR = linker.ld
ROOTFS = rootfs
GRUBCFG = $(ROOTFS)/boot/grub/grub.cfg
KERNEL = $(ROOTFS)/boot/kernel
CFLAGS = \
-std=c99 \
-pedantic \
-Wall \
-Wextra \
-ffreestanding \
-fno-builtin \
-fno-stack-protector \
-I../../include
OBJS = main.c.o start.S.o
all: run
run: $(IMAGE)
qemu-system-i386 -cdrom $< -serial stdio -display none
clean:
rm -f $(IMAGE) $(KERNEL) $(OBJS)
$(IMAGE): $(GRUBCFG) $(KERNEL)
grub-mkrescue $(ROOTFS) -o $@
$(KERNEL): $(LINKERSCR) $(OBJS)
$(CC) -T $(LINKERSCR) -o $@ $(OBJS) -ffreestanding -nostdlib -lgcc -lkernaux -Wl,-L../..
grub-file --is-x86-multiboot2 $@
%.c.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
%.S.o: %.S
$(AS) $< -o $@

View File

@ -0,0 +1,38 @@
OUTPUT_ARCH("i386")
ENTRY(_start)
_kernel_offset = 0xC0000000; /* 3 GB */
_kernel_phys_base = 4M;
_kernel_virt_base = (_kernel_phys_base + _kernel_offset);
_kernel_stack_size = _kernel_stack_end - _kernel_stack_start;
SECTIONS
{
. = _kernel_phys_base;
.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)
}
_kernel_size = . - _kernel_phys_base;
}

View File

@ -0,0 +1,35 @@
#include <stdint.h>
#include <kernaux/asm/i386.h>
#include <kernaux/drivers/console.h>
#include <kernaux/multiboot2.h>
void halt();
static void panic(const char *str);
void main(
const uint32_t multiboot2_magic,
const struct KernAux_Multiboot2 *const multiboot2_info
) {
if (multiboot2_magic != KERNAUX_MULTIBOOT2_MAGIC) {
panic("Multiboot 2 magic number is invalid");
}
KernAux_Multiboot2_print(multiboot2_info, kernaux_console_printf);
if (!KernAux_Multiboot2_is_valid(multiboot2_info)) {
panic("Multiboot 2 info is invalid");
}
}
void halt()
{
panic("Kernel main function returned");
}
void panic(const char *const str)
{
kernaux_console_printf("panic: %s\n", str);
kernaux_asm_i386_hang();
}

View File

@ -0,0 +1,5 @@
set timeout=0
menuentry "Kernel" {
multiboot2 /boot/kernel hello kernel
}

View File

@ -0,0 +1,48 @@
.set MULTIBOOT_MAGIC, 0xE85250D6
.set MULTIBOOT_ARCH, 0
.set MULTIBOOT_LENGTH, 16 + 8
.set MULTIBOOT_CHECKSUM, -(MULTIBOOT_MAGIC + MULTIBOOT_ARCH + MULTIBOOT_LENGTH)
.section .multiboot
.align 4
.long MULTIBOOT_MAGIC
.long MULTIBOOT_ARCH
.long MULTIBOOT_LENGTH
.long MULTIBOOT_CHECKSUM
.long 0
.long 8
.section .bss
.global _kernel_stack_start
.global _kernel_stack_end
.align 16
_kernel_stack_start:
.skip 16384 # 16 KiB
_kernel_stack_end:
.section .text
.global _start
.type _start, @function
.type main, @function
.type halt, @function
_start:
mov $_kernel_stack_end, %esp // Initialize stack
push %ebx // Multiboot information pointer
push %eax // Multiboot magic number
call main
call halt
.size _start, . - _start