From 958e2dae042ca9e28f23e509d541730f30fa8502 Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Thu, 8 Apr 2021 13:07:17 +0200 Subject: [PATCH] Switch to multiboot2 and improve interrupt management --- .gitignore | 2 ++ src/Makefile | 9 +++--- src/boot/boot.S | 63 ++++++++++++++++++++++++++-------------- src/bringelle.c | 16 ++++++++-- src/infos.bin | Bin 0 -> 200 bytes src/linker.ld | 27 +++++++++++++++++ src/utils/8042.h | 1 + src/utils/multiboot.c | 39 +++++++++++++++++++++++++ src/utils/multiboot.h | 32 ++++++++++++++++++++ src/utils/pic.c | 22 ++++++-------- src/utils/pic.h | 2 +- src/utils/types.h | 1 + tools/bochsrc | 2 ++ tools/gen_grub_cdrom.sh | 31 ++++++++++++++++++++ 14 files changed, 206 insertions(+), 41 deletions(-) create mode 100644 src/infos.bin create mode 100644 src/linker.ld create mode 100644 src/utils/multiboot.c create mode 100644 src/utils/multiboot.h create mode 100644 tools/bochsrc create mode 100755 tools/gen_grub_cdrom.sh diff --git a/.gitignore b/.gitignore index 066e420..9f6575c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /src/bringelle **/*.o .vscode +**/*.img +**/*.iso diff --git a/src/Makefile b/src/Makefile index b95e38d..28081af 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,6 @@ EXEC := bringelle CC := gcc -c -m32 -fno-pie -fno-builtin -fno-stack-protector +LD_SCRIPT := linker.ld # Note that BOOT_OBJ do not match boot.S # Indeed boot.o generated by boot.S should appear @@ -10,19 +11,19 @@ UTILS_OBJ := $(addsuffix .o,$(basename $(shell find ./utils -name "*.[c|S]"))) all: $(EXEC) $(EXEC): boot/boot.o $(UTILS_OBJ) bringelle.o - ld -Ttext=0x00100000 -melf_i386 -nostdlib --oformat=binary -o bringelle $^ + ld -n -T $(LD_SCRIPT) -nostdlib -o bringelle $^ %.o: %.S as --32 -o $@ $^ -mx86-used-note=no %.o: %.c $(CC) -o $@ $< - objcopy --remove-section .note.gnu.property $@ - + #objcopy --remove-section .note.gnu.property $@ + clean: rm -f $(EXEC) find ./ -name "*.o" -delete -.PHONY: clean +.PHONY: clean cdrom diff --git a/src/boot/boot.S b/src/boot/boot.S index e3830eb..469cc82 100644 --- a/src/boot/boot.S +++ b/src/boot/boot.S @@ -1,29 +1,50 @@ +.globl _start +.globl MB_INFO .extern bringelle .extern gdt_memcpy -.globl _start -.text +.extern mb_load_fb_tag -.set MB_MAGIC, 0x1BADB002 -.set MB_FLAGS, 0x00010000 -.set MB_CHECKSUM, -(MB_MAGIC+MB_FLAGS) -.set MB_HEADER_ADDR, mb_header -.set MB_LOAD_ADDR, mb_header -.set MB_LOAD_END_ADDR, 0x0 -.set MB_BSS_END_ADDR, 0x0 -.set MB_ENTRY_ADDR, _start +.section .multiboot -mb_header: -.align 4 -.long MB_MAGIC -.long MB_FLAGS -.long MB_CHECKSUM -.long MB_HEADER_ADDR -.long MB_LOAD_ADDR -.long MB_LOAD_END_ADDR -.long MB_BSS_END_ADDR -.long MB_ENTRY_ADDR +.set MB_MAGIC, 0xE85250D6 +.set MB_ARCH, 0x00000000 +.set MB_HEADER_LENGTH, (mb_header_end-mb_header_start) +.set MB_CHECKSUM, -(MB_MAGIC+MB_ARCH+MB_HEADER_LENGTH) + +mb_header_start: +.align 8 +.int MB_MAGIC +.int MB_ARCH +.int MB_HEADER_LENGTH +.int MB_CHECKSUM +# ----------- Address tag +.align 8 +.short 2 +.short 0 # Not optional +.int 24 # Size +.int mb_header_start # header_addr +.int mb_header_start # load_addr +.int 0x0 # load_end_addr +.int 0x0 # bss_end_addr +# ----------- Addr tag +.align 8 +.short 0x3 +.short 0 +.int 12 +.int _start +# ----------- End tag +.align 8 +.int 0x0 +.int 0x8 +mb_header_end: + +.section .text + +MB_INFO: + .int 0xABCDEF # Will contains the Multiboot2 information data structure address _start: +mov %ebx, (MB_INFO) # Copy GDT into memory then load its register call gdt_memcpy @@ -44,7 +65,7 @@ cs_new: # Update stack segment movw $0x18, %ax movw %ax, %ss -movl $0x20000,%esp +movl $0x50000,%esp # Start kernel main function call bringelle diff --git a/src/bringelle.c b/src/bringelle.c index 013308f..9e17906 100644 --- a/src/bringelle.c +++ b/src/bringelle.c @@ -1,11 +1,23 @@ #include "utils/print.h" #include "utils/asm.h" #include "utils/pic.h" +#include "utils/8042.h" +#include "utils/multiboot.h" + +extern char *name_addr; void bringelle(){ - clear(); + + // clear(); + //print("Booting Bringelle..."); + //pic_enable_interrupt(); print("Booting Bringelle..."); - pic_enable_interrupt(); + MBI_TAG_BL_NAME bl_infos; + if(!mb_load_bl_name(&bl_infos)){ + print(bl_infos.name); + print(" detected!"); + } + while(1); } diff --git a/src/infos.bin b/src/infos.bin new file mode 100644 index 0000000000000000000000000000000000000000..770850f8bc433e7fcfb0de7ca2d0bc2e04914488 GIT binary patch literal 200 zcmeBRWB>zEAjtz}2{06VddCP7<^=IIY;;TSlnOEdnLFF6aWAK literal 0 HcmV?d00001 diff --git a/src/linker.ld b/src/linker.ld new file mode 100644 index 0000000..fdc7b1b --- /dev/null +++ b/src/linker.ld @@ -0,0 +1,27 @@ +ENTRY(_start) +OUTPUT_FORMAT(elf32-i386) +OUTPUT_ARCH(i386) + +SECTIONS { + + . = 1M; + .text : + { + *(.multiboot) + *(.text) + } + .rodata : + { + *(.rodata) + } + .data : + { + *(.data) + } + .bss : + { + *(.bss) + *(COMMON) + } + +} \ No newline at end of file diff --git a/src/utils/8042.h b/src/utils/8042.h index 1fecf2a..068a0ef 100644 --- a/src/utils/8042.h +++ b/src/utils/8042.h @@ -58,6 +58,7 @@ void _8042_keypress(); 'n',\ ',',\ ';',\ + ':',\ } #endif \ No newline at end of file diff --git a/src/utils/multiboot.c b/src/utils/multiboot.c new file mode 100644 index 0000000..891bd57 --- /dev/null +++ b/src/utils/multiboot.c @@ -0,0 +1,39 @@ +#include "multiboot.h" + +extern u8* MB_INFO; + +char mb_load_tag(char **data, char type){ + char *c_info_size=MB_INFO; + char *c_tag_type=c_info_size+8; + char *c_tag_size=c_info_size+12; + + for(int i=0;i<10;i++){ + int tag_type=*((int*)c_tag_type); + int tag_size=*((int*)c_tag_size); + if(tag_type==type){ + *data=c_tag_type; + return 0; + } + + c_tag_type=c_tag_type+tag_size+4; + // Skip padding for 64 bits + int p=c_tag_type; + while((p & 0x7) != 0) + p++; + // Assign address after padding + c_tag_type=p; + c_tag_size=c_tag_type+4; + + } + return 1; +} +char mb_load_bl_name(MBI_TAG_BL_NAME *data){ + char *to_load; + if(!mb_load_tag(&to_load,2)){ + memcpy(to_load,data,8); + to_load+=8; + data->name=to_load; + return 0; + } + return 1; +} diff --git a/src/utils/multiboot.h b/src/utils/multiboot.h new file mode 100644 index 0000000..4194d00 --- /dev/null +++ b/src/utils/multiboot.h @@ -0,0 +1,32 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include "types.h" + +typedef struct MBI_TAG_HEADER { + u32 type; + u32 size; +} __attribute__((packed)) MBI_TAG_HEADER; + +typedef struct MBI_TAG_BL_NAME { + MBI_TAG_HEADER header; + u8 *name; +} __attribute__((packed)) MBI_TAG_BL_NAME; + + +typedef struct MBI_TAG_FB { + MBI_TAG_HEADER header; + u64 framebuffer_addr; + u32 framebuffer_pitch; + u32 framebuffer_width; + u32 framebuffer_height; + u8 framebuffer_bpp; + u8 framebuffer_type; + u8 reserved; + u8 *color_infos; +}__attribute__((packed)) MBI_TAG_FB; + + +char mb_load_tag(char **data, char type); +char mb_load_bl_name(MBI_TAG_BL_NAME *data); +#endif \ No newline at end of file diff --git a/src/utils/pic.c b/src/utils/pic.c index f77eb70..4459f0d 100644 --- a/src/utils/pic.c +++ b/src/utils/pic.c @@ -3,8 +3,8 @@ #include "mem.h" struct IDT_REGISTER IDTR={ - 90*8, - 0 + 100*8, + 0x0 }; /// Bridge between IDT and functions call @@ -22,13 +22,12 @@ asm ( extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT; - void pic_enable_interrupt(){ // Map first default 32 entries - for(int i=0;i<90;i++){ - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_TYPE_1}); + for(int i=0;i<100;i++){ + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_TYPE_1},i); if(i==32) - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_TYPE_1}); + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_TYPE_1},i); } // Now configure 8952A @@ -39,7 +38,7 @@ void pic_enable_interrupt(){ // ICW2: Map IRQ index to entry into the IDT outbj(0x21,0x20); // Start interrupt at offset 0x20 in IDT (index 32) - outbj(0xA1,0x50); // Start interrupt at offset 0x50 in IDT (index 80) + outbj(0xA1,0x70); // Start interrupt at offset 0x50 in IDT (index 80) // ICW3: Indicate the connection between master and slave outbj(0x21,0x02); // Slave connected to pin 2 @@ -51,15 +50,12 @@ void pic_enable_interrupt(){ asm("lidtl (IDTR)"); asm("sti"); - } -void pic_add_idt_entry(IDT_ENTRY entry){ - static int cur_offset=0; +void pic_add_idt_entry(IDT_ENTRY entry, int id){ int descriptor[2]; descriptor[0]=entry.offset & 0xFFFF | entry.segment << 16; descriptor[1]=entry.type & 0xFFFF | entry.offset & 0xFFFF0000; - memcpy((void*)descriptor, (void *)(IDTR.base+cur_offset),8); - cur_offset+=8; -} \ No newline at end of file + memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8); +} diff --git a/src/utils/pic.h b/src/utils/pic.h index b8f98ac..2734437 100644 --- a/src/utils/pic.h +++ b/src/utils/pic.h @@ -17,6 +17,6 @@ struct IDT_REGISTER { } __attribute__((packed)); void pic_enable_interrupt(); -void pic_add_idt_entry(IDT_ENTRY entry); +void pic_add_idt_entry(IDT_ENTRY entry,int id); #endif \ No newline at end of file diff --git a/src/utils/types.h b/src/utils/types.h index b06b160..ce49701 100644 --- a/src/utils/types.h +++ b/src/utils/types.h @@ -4,5 +4,6 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; +typedef unsigned long long u64; #endif diff --git a/tools/bochsrc b/tools/bochsrc new file mode 100644 index 0000000..fd9fe69 --- /dev/null +++ b/tools/bochsrc @@ -0,0 +1,2 @@ +romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot +vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest diff --git a/tools/gen_grub_cdrom.sh b/tools/gen_grub_cdrom.sh new file mode 100755 index 0000000..1b65bf8 --- /dev/null +++ b/tools/gen_grub_cdrom.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# Ensure to abort on error +set -e + +wai=$(dirname $(readlink -f "$0")) # Current script directory +outdir="${wai}/../" +cdrom="${outdir}/cdrom.img" +isodir="$(mktemp -d)" # Mount point (where the floppy will be mounted temporally +kernel="$outdir/src/bringelle" + +[ ! -e "$kernel" ] && { echo "Bringelle not found!"; exit 1; } + +check_for () { + command -v "$1" &>/dev/null || { echo "Command $1 not found!"; exit 1; } +} + +check_for grub-mkconfig + +mkdir -p $isodir/boot/grub +cat <> $isodir/boot/grub/grub.cfg +set timeout=0 +menuentry "kernel" { + multiboot2 /boot/bringelle + boot +} +EOT +cp $kernel "$isodir/boot/" +grub-mkrescue -o "$cdrom" $isodir + +rm -rf "$isodir"