Load kernel with a .data segment.

This commit is contained in:
Alexander Myltsev 2022-11-20 19:48:55 +03:00
parent f860ec1ef0
commit b8604932eb
6 changed files with 33 additions and 13 deletions

View File

@ -25,11 +25,11 @@ fs.img: kernel.bin tools/mkfs
image.bin: mbr.bin fs.img image.bin: mbr.bin fs.img
cat $^ >$@ cat $^ >$@
kernel.bin: kernel.o console.o drivers/vga.o string.o drivers/ata.o cpu/vectors.o cpu/idt.o kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o string.o drivers/ata.o cpu/vectors.o cpu/idt.o
$(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ $(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^
%.o: %.c %.o: %.c
$(CC) -m32 -ffreestanding -c -g $< -o $@ $(CC) -m32 -ffreestanding -Wall -Werror -c -g $< -o $@
%.o: %.S %.o: %.S
$(AS) --32 -g $^ -o $@ $(AS) --32 -g $^ -o $@

View File

@ -30,7 +30,7 @@ void set_idt_gate(int n, uint32_t handler) {
} }
// defined in vectors.S // defined in vectors.S
extern uint32_t default_handlers[IDT_HANDLERS]; extern uint32_t default_handlers[];
void init_idt() { void init_idt() {
for (int i = 0; i < IDT_HANDLERS; i++) { for (int i = 0; i < IDT_HANDLERS; i++) {
@ -64,7 +64,11 @@ const char *exception_messages[] = {
#define ARRLEN(a) (sizeof(a) / sizeof(a[0])) #define ARRLEN(a) (sizeof(a) / sizeof(a[0]))
isr_t interrupt_handlers[IDT_HANDLERS]; static isr_t interrupt_handlers[IDT_HANDLERS];
void register_interrupt_handler(uint8_t i, isr_t handler) {
interrupt_handlers[i] = handler;
}
void trap(registers_t *r) { void trap(registers_t *r) {
if (r->int_no < 32) { if (r->int_no < 32) {

View File

@ -45,7 +45,7 @@ vector\i :
.global default_handlers .global default_handlers
default_handlers: default_handlers:
.set i,0 .set i,0
.rept 256 .rept 40
irq_insertX %i irq_insertX %i
.set i, i+1 .set i, i+1
.endr .endr

View File

@ -1,25 +1,25 @@
#pragma once #pragma once
static unsigned char port_byte_in(unsigned short port) { static inline unsigned char port_byte_in(unsigned short port) {
unsigned char result; unsigned char result;
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); __asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
return result; return result;
} }
static unsigned short port_word_in(unsigned short port) { static inline unsigned short port_word_in(unsigned short port) {
unsigned short result; unsigned short result;
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
return result; return result;
} }
static void port_byte_out(unsigned short port, unsigned char data) { static inline void port_byte_out(unsigned short port, unsigned char data) {
__asm__("outb %%al, %%dx" : : "a" (data), "d" (port)); __asm__("outb %%al, %%dx" : : "a" (data), "d" (port));
} }
static void port_word_out(unsigned short port, unsigned short data) { static inline void port_word_out(unsigned short port, unsigned short data) {
__asm__("outw %%ax, %%dx" : : "a" (data), "d" (port)); __asm__("outw %%ax, %%dx" : : "a" (data), "d" (port));
} }
static void port_long_out(unsigned short port, unsigned int data) { static inline void port_long_out(unsigned short port, unsigned int data) {
__asm__("outl %%eax, %%dx" : : "a" (data), "d" (port)); __asm__("outl %%eax, %%dx" : : "a" (data), "d" (port));
} }

View File

@ -1,21 +1,27 @@
asm(".asciz \"kernel start\""); asm(".asciz \"kernel start\"");
#include "console.h"
#include "cpu/isr.h" #include "cpu/isr.h"
#include "drivers/keyboard.h"
#include "drivers/vga.h" #include "drivers/vga.h"
#include "drivers/ata.h" #include "drivers/ata.h"
#include "drivers/misc.h" #include "drivers/misc.h"
void _start() { void _start() {
init_keyboard();
load_idt(); load_idt();
sti(); sti();
char buf[512]; char buf[512];
vga_clear_screen(); vga_clear_screen();
vga_print_string("YABLOKO\n"); printk("YABLOKO\n");
read_sectors_ATA_PIO((uint32_t)buf, 10, 1); read_sectors_ATA_PIO((uint32_t)buf, 10, 1);
vga_print_string(buf); printk(buf);
while (1) {
asm("pause");
}
asm("hlt"); asm("hlt");
qemu_shutdown(); qemu_shutdown();
} }

12
mbr.S
View File

@ -13,6 +13,9 @@ _start:
.equ ELF32_ENTRY_OFFSET, 0x18 .equ ELF32_ENTRY_OFFSET, 0x18
.equ ELF32_PHDR_OFFSET, 0x1c .equ ELF32_PHDR_OFFSET, 0x1c
.equ ELF32_PHENTSIZE_OFFSET, ELF32_PHDR_OFFSET + 14
.equ ELF32_PHNUM_OFFSET, ELF32_PHENTSIZE_OFFSET + 2
.equ ELF32_PHDR_P_OFFSET, 4
.equ ELF32_PHDR_FILESZ_OFFSET, 4*4 .equ ELF32_PHDR_FILESZ_OFFSET, 4*4
.equ KERNEL_OFFSET, 0x1000 .equ KERNEL_OFFSET, 0x1000
@ -31,8 +34,15 @@ load_kernel:
mov KERNEL_OFFSET + ELF32_ENTRY_OFFSET, %si mov KERNEL_OFFSET + ELF32_ENTRY_OFFSET, %si
mov %si, entry // store entry point mov %si, entry // store entry point
mov KERNEL_OFFSET + ELF32_PHDR_OFFSET, %di mov KERNEL_OFFSET + ELF32_PHNUM_OFFSET, %ax
dec %ax // no offset to the first entry
mulb KERNEL_OFFSET + ELF32_PHENTSIZE_OFFSET
mov %ax, %di
add KERNEL_OFFSET + ELF32_PHDR_OFFSET, %di
// now di holds offset to the last phentry
mov KERNEL_OFFSET + ELF32_PHDR_FILESZ_OFFSET(%di), %ax mov KERNEL_OFFSET + ELF32_PHDR_FILESZ_OFFSET(%di), %ax
add KERNEL_OFFSET + ELF32_PHDR_P_OFFSET(%di), %ax
sub $0x1000, %ax // we won't load the header sub $0x1000, %ax // we won't load the header
add $SECTOR_SIZE - 1, %ax add $SECTOR_SIZE - 1, %ax
shr $SECTOR_SHIFT, %ax // round up to sector count shr $SECTOR_SHIFT, %ax // round up to sector count