Switch to multiboot2 and improve interrupt management
This commit is contained in:
parent
db553d0582
commit
958e2dae04
14 changed files with 206 additions and 41 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
|||
/src/bringelle
|
||||
**/*.o
|
||||
.vscode
|
||||
**/*.img
|
||||
**/*.iso
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
BIN
src/infos.bin
Normal file
BIN
src/infos.bin
Normal file
Binary file not shown.
27
src/linker.ld
Normal file
27
src/linker.ld
Normal file
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -58,6 +58,7 @@ void _8042_keypress();
|
|||
'n',\
|
||||
',',\
|
||||
';',\
|
||||
':',\
|
||||
}
|
||||
|
||||
#endif
|
39
src/utils/multiboot.c
Normal file
39
src/utils/multiboot.c
Normal file
|
@ -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;
|
||||
}
|
32
src/utils/multiboot.h
Normal file
32
src/utils/multiboot.h
Normal file
|
@ -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
|
|
@ -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;
|
||||
memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8);
|
||||
}
|
|
@ -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
|
|
@ -4,5 +4,6 @@
|
|||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#endif
|
||||
|
|
2
tools/bochsrc
Normal file
2
tools/bochsrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
|
||||
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
|
31
tools/gen_grub_cdrom.sh
Executable file
31
tools/gen_grub_cdrom.sh
Executable file
|
@ -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 <<EOT >> $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"
|
Loading…
Add table
Reference in a new issue