Reorganised files into directories

This commit is contained in:
Maciej Krzyżanowski 2024-04-17 12:47:47 +02:00
parent ccd3538d1f
commit 226ad82b29
17 changed files with 398 additions and 291 deletions

1
.gitignore vendored Normal file → Executable file
View File

@ -5,3 +5,4 @@ mkos.bin
mkos.iso
bx_enh_dbg.ini
dysk.img
.idea/

View File

@ -1,4 +0,0 @@
#!/bin/bash
../Kompilator/cross/bin/i686-elf-as boot.s -o boot.o
../Kompilator/cross/bin/i686-elf-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
../Kompilator/cross/bin/i686-elf-gcc -T linker.ld -o mkos.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc

4
bochsrc → config/bochsrc Normal file → Executable file
View File

@ -1,9 +1,9 @@
megs: 32
cpu: count=1, ips=9000000
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=cdrom, path="mkos.iso", status=inserted
ata0-master: type=cdrom, path="../build/mkos.iso", status=inserted
ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata1-master: type=disk, path="dysk.img", mode=flat
ata1-master: type=disk, path="../filesystem/dysk.img", mode=flat
boot: cdrom
display_library: x, options="gui_debug"
magic_break: enabled=1

0
grub.cfg → config/grub.cfg Normal file → Executable file
View File

122
idt.h
View File

@ -1,122 +0,0 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "print.h"
// Interrupt Gate Entry
struct idt_int_gate
{
uint32_t offset;
uint16_t segment_selector;
bool is_present;
int permission_level;
bool is_32_bit;
};
struct idt_int_gate idt_int_gate_create(
uint16_t segment_selector,
uint32_t offset)
{
struct idt_int_gate new_gate;
new_gate.segment_selector = segment_selector;
new_gate.offset = offset;
new_gate.is_present = true;
new_gate.permission_level = 0;
new_gate.is_32_bit = true;
return new_gate;
}
uint64_t idt_int_gate_encode(struct idt_int_gate gate)
{
uint64_t gate_encoded = 0;
// Insert offset
gate_encoded |= ((((uint64_t) gate.offset) & 0xFFFF0000) << 32);
gate_encoded |= ((((uint64_t) gate.offset) & 0x0000FFFF));
// Insert segment selector
gate_encoded |= ((((uint64_t) gate.segment_selector)) << 16);
// Insert P(resent) bit
gate_encoded |= ((((uint64_t) gate.is_present)) << 47);
// Inesrt DPL
gate_encoded |= ((((uint64_t) gate.permission_level)) << 45);
// Insert D (size of gate)
gate_encoded |= ((((uint64_t) gate.is_32_bit)) << 43);
// Insert some magic bits
uint8_t magic_bits = 0x30;
gate_encoded |= ((((uint64_t) magic_bits)) << 37);
return gate_encoded;
}
struct __attribute__((__packed__)) idt_table
{
// Size in bytes minus one!
uint16_t size_in_bytes_m1;
uint64_t *dest_pointer;
struct idt_int_gate gates[256];
};
void apply_idt_table(struct idt_table table)
{
int entries_count = (table.size_in_bytes_m1 + 1) / 8;
for (int i = 0; i < entries_count; i++)
{
uint64_t entry_encoded = idt_int_gate_encode(table.gates[i]);
uint64_t *dest_address = table.dest_pointer + i;
*dest_address = entry_encoded;
}
__asm__("lidt (%0)": :"r"(&table));
}
void default_int_handler()
{
__asm__("iret");
}
void idt_setup()
{
uintptr_t default_isr_ptr;
__asm__("mov $default_isr, %%eax": : :"eax");
__asm__("mov %%eax, %0;": "=r"(default_isr_ptr):);
uintptr_t clock_isr_ptr;
__asm__ volatile("mov $clock_isr, %%eax;"
"mov %%eax, %0;"
:
"=r" (clock_isr_ptr)
:
:
"eax"
);
struct idt_table table;
table.size_in_bytes_m1 = 256 * 8 - 1;
table.dest_pointer = (uint64_t*)0x500000;
for (int i = 0; i < 256; i++)
{
struct idt_int_gate new_gate
= idt_int_gate_create(0x8, default_isr_ptr);
table.gates[i] = new_gate;
}
table.gates[0x70] = idt_int_gate_create(0x8, clock_isr_ptr);
apply_idt_table(table);
terminal_newline();
terminal_writenumpad(default_isr_ptr, 16, 16);
__asm__ volatile("sti");
}

View File

@ -1,4 +0,0 @@
#!/bin/bash
cp mkos.bin isodir/boot/mkos.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o mkos.iso isodir

4
scripts/compile.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
../../Kompilator/cross/bin/i686-elf-as ../source/boot.s -o ../build/boot.o
../../Kompilator/cross/bin/i686-elf-gcc -c ../source/kernel.c -o ../build/kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
../../Kompilator/cross/bin/i686-elf-gcc -T ../source/linker.ld -o ../build/mkos.bin -ffreestanding -O2 -nostdlib ../build/boot.o ../build/kernel.o -lgcc

View File

@ -1 +1 @@
indent -nbad -bap -nbc -bbo -hnl -bl -bli0 -brs -c33 -cd33 -ncdb -ncdw -ci4 -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1 kernel.c
indent -nbad -bap -nbc -bbo -hnl -bl -bli0 -brs -c33 -cd33 -ncdb -ncdw -ci4 -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1 source/kernel.c

4
scripts/makeiso.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
cp ../build/mkos.bin ../isodir/boot/mkos.bin
cp ../config/grub.cfg ../isodir/boot/grub/grub.cfg
grub-mkrescue -o ../build/mkos.iso ../isodir

View File

@ -2,5 +2,5 @@
./compile.sh
./makeiso.sh
# Remove lock in case of bad shutdown, it makes debugging easier
rm dysk.img.lock
bochs
rm ../filesystem/dysk.img.lock
bochs -f ../config/bochsrc

114
boot.s → source/boot.s Normal file → Executable file
View File

@ -32,7 +32,7 @@
.global stack_top
.global stack_bottom
stack_bottom:
/* Stos o wielkości 16 KB */
/* Stos o wielkości 64 KB */
.skip 65536
stack_top:
@ -45,83 +45,55 @@ clock_pos: .int 0x0
Oznaczenie startu, tu zaczyna się kod kernela!
*/
.section .text
.global default_isr
.type default_isr, @function
default_isr:
cli
push %eax
mov $0x0F41, %eax
add int_count, %eax
mov %ax, 0xb8000
incl int_count
.macro isr number
.global isr_\number
.type isr_\number, @function
isr_\number :
pusha
push $\number
cmpl $0x5, int_count
jne end
call isr_common_handler
movl $0x0, int_count
add $4, %esp
end:
xchg %bx, %bx
mov $0x20, %al
outb %al, $0x20
mov $0x20, %al
outb %al, $0xA0
pop %eax
popa
sti
iretl
.endm
.global clock_isr
.type clock_isr, @function
clock_isr:
cli
push %eax
//xchg %bx, %bx
mov $0x0F41, %ax
add clock_count, %ax
mov clock_pos, %edx
shl $1, %edx
add $0xb8002, %edx
movw %ax, (%edx)
incl clock_count
cmpl $0x1F, clock_count
jne end2
movl $0x0, clock_count
end2:
incl clock_pos
cmpl $0x7CF, clock_pos
jne end3
movl $0x0, clock_pos
end3:
//xchg %bx, %bx
mov $0x0c, %al
outb %al, $0x70
inb $0x71
mov $0x20, %al
outb %al, $0x20
mov $0x20, %al
outb %al, $0xA0
// EOI
pop %eax
sti
iretl
isr 0
isr 1
isr 2
isr 3
isr 4
isr 5
isr 6
isr 7
isr 8
isr 9
isr 10
isr 11
isr 12
isr 13
isr 14
isr 15
isr 16
isr 17
isr 18
isr 19
isr 20
isr 21
isr 22
isr 23
isr 24
isr 25
isr 26
isr 27
isr 28
isr 29
isr 30
isr 31
.global _start
.type _start, @function

0
gdt.h → source/gdt.h Normal file → Executable file
View File

210
source/idt.h Executable file
View File

@ -0,0 +1,210 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "print.h"
#include "utils.h"
extern void isr_0();
extern void isr_1();
extern void isr_2();
extern void isr_3();
extern void isr_4();
extern void isr_5();
extern void isr_6();
extern void isr_7();
extern void isr_8();
extern void isr_9();
extern void isr_10();
extern void isr_11();
extern void isr_12();
extern void isr_13();
extern void isr_14();
extern void isr_15();
extern void isr_16();
extern void isr_17();
extern void isr_18();
extern void isr_19();
extern void isr_20();
extern void isr_21();
extern void isr_22();
extern void isr_23();
extern void isr_24();
extern void isr_25();
extern void isr_26();
extern void isr_27();
extern void isr_28();
extern void isr_29();
extern void isr_30();
extern void isr_31();
// Interrupt Gate Entry
struct idt_int_gate
{
uint32_t offset;
uint16_t segment_selector;
bool is_present;
int permission_level;
bool is_32_bit;
};
struct idt_int_gate idt_int_gate_create(
uint16_t segment_selector,
uint32_t offset)
{
struct idt_int_gate new_gate;
new_gate.segment_selector = segment_selector;
new_gate.offset = offset;
new_gate.is_present = true;
new_gate.permission_level = 0;
new_gate.is_32_bit = true;
return new_gate;
}
uint64_t idt_int_gate_encode(struct idt_int_gate gate)
{
uint64_t gate_encoded = 0;
// Insert offset
gate_encoded |= ((((uint64_t) gate.offset) & 0xFFFF0000) << 32);
gate_encoded |= ((((uint64_t) gate.offset) & 0x0000FFFF));
// Insert segment selector
gate_encoded |= ((((uint64_t) gate.segment_selector)) << 16);
// Insert P(resent) bit
gate_encoded |= ((((uint64_t) gate.is_present)) << 47);
// Inesrt DPL
gate_encoded |= ((((uint64_t) gate.permission_level)) << 45);
// Insert D (size of gate)
gate_encoded |= ((((uint64_t) gate.is_32_bit)) << 43);
// Insert some magic bits
uint8_t magic_bits = 0x30;
gate_encoded |= ((((uint64_t) magic_bits)) << 37);
return gate_encoded;
}
struct __attribute__((__packed__)) idt_table
{
// Size in bytes minus one!
uint16_t size_in_bytes_m1;
uint64_t *dest_pointer;
struct idt_int_gate gates[256];
};
void apply_idt_table(struct idt_table table)
{
int entries_count = (table.size_in_bytes_m1 + 1) / 8;
for (int i = 0; i < entries_count; i++)
{
uint64_t entry_encoded = idt_int_gate_encode(table.gates[i]);
uint64_t *dest_address = table.dest_pointer + i;
*dest_address = entry_encoded;
}
__asm__("lidt (%0)": :"r"(&table));
}
void default_int_handler()
{
__asm__("iretl");
}
void clock_int_handler()
{
printf("\n");
set_interrupts(false);
int old_row = terminal_row;
int old_col = terminal_column;
terminal_row = 0;
terminal_column = 0;
display_date();
terminal_row = old_row;
terminal_column = old_col;
// Zero CMOS C register
// Select C register
outb(0x70, 0x0c);
// Read C register contents (which resets it, so RTC can send next requests)
inb(0x71);
// Send EOI to slave PIC (because IRQ 8 from RTC belongs to this PIC)
outb(0xA0, 0x20);
// Send EOI to master PIC (because master also needs to acknowledge
// handling of interrupt even if it came from slave)
outb(0x20, 0x20);
set_interrupts(true);
printf("Updated!");
}
void idt_setup()
{
struct idt_table table;
table.size_in_bytes_m1 = 256 * 8 - 1;
table.dest_pointer = (uint64_t*)0x500000;
// Empty ISR-s, for the sake of completeness
for (int i = 0; i < 256; i++)
{
struct idt_int_gate new_gate
= idt_int_gate_create(0x8, (intptr_t)default_int_handler);
table.gates[i] = new_gate;
}
// Clock ISR
table.gates[0x28] = idt_int_gate_create(0x8, (intptr_t)clock_int_handler);
// 0-31 ISR-s
table.gates[0] = idt_int_gate_create(0x8, (intptr_t)isr_0);
table.gates[1] = idt_int_gate_create(0x8, (intptr_t)isr_1);
table.gates[2] = idt_int_gate_create(0x8, (intptr_t)isr_2);
table.gates[3] = idt_int_gate_create(0x8, (intptr_t)isr_3);
table.gates[4] = idt_int_gate_create(0x8, (intptr_t)isr_4);
table.gates[5] = idt_int_gate_create(0x8, (intptr_t)isr_5);
table.gates[6] = idt_int_gate_create(0x8, (intptr_t)isr_6);
table.gates[7] = idt_int_gate_create(0x8, (intptr_t)isr_7);
table.gates[8] = idt_int_gate_create(0x8, (intptr_t)isr_8);
table.gates[9] = idt_int_gate_create(0x8, (intptr_t)isr_9);
table.gates[10] = idt_int_gate_create(0x8, (intptr_t)isr_10);
table.gates[11] = idt_int_gate_create(0x8, (intptr_t)isr_11);
table.gates[12] = idt_int_gate_create(0x8, (intptr_t)isr_12);
table.gates[13] = idt_int_gate_create(0x8, (intptr_t)isr_13);
table.gates[14] = idt_int_gate_create(0x8, (intptr_t)isr_14);
table.gates[15] = idt_int_gate_create(0x8, (intptr_t)isr_15);
table.gates[16] = idt_int_gate_create(0x8, (intptr_t)isr_16);
table.gates[17] = idt_int_gate_create(0x8, (intptr_t)isr_17);
table.gates[18] = idt_int_gate_create(0x8, (intptr_t)isr_18);
table.gates[19] = idt_int_gate_create(0x8, (intptr_t)isr_19);
table.gates[20] = idt_int_gate_create(0x8, (intptr_t)isr_20);
table.gates[21] = idt_int_gate_create(0x8, (intptr_t)isr_21);
table.gates[22] = idt_int_gate_create(0x8, (intptr_t)isr_22);
table.gates[23] = idt_int_gate_create(0x8, (intptr_t)isr_23);
table.gates[24] = idt_int_gate_create(0x8, (intptr_t)isr_24);
table.gates[25] = idt_int_gate_create(0x8, (intptr_t)isr_25);
table.gates[26] = idt_int_gate_create(0x8, (intptr_t)isr_26);
table.gates[27] = idt_int_gate_create(0x8, (intptr_t)isr_27);
table.gates[28] = idt_int_gate_create(0x8, (intptr_t)isr_28);
table.gates[29] = idt_int_gate_create(0x8, (intptr_t)isr_29);
table.gates[30] = idt_int_gate_create(0x8, (intptr_t)isr_30);
table.gates[31] = idt_int_gate_create(0x8, (intptr_t)isr_31);
apply_idt_table(table);
__asm__ volatile("sti");
}
void isr_common_handler(int number)
{
printf("Interrupt %d\n", number);
}

53
source/kernel.c Executable file
View File

@ -0,0 +1,53 @@
#include <stddef.h>
#include <stdint.h>
#include "gdt.h"
#include "print.h"
#include "idt.h"
#include "utils.h"
void kernel_main(void)
{
terminal_initialize();
print_texts();
gdt_setup();
idt_setup();
// 8 of master PIC interrupt numbers
// and 8 of slave PIC interrupt numbers
// right after 0-31 interrupt numbers reserved for processor
PIC_remap(0x20, 0x28);
// Set RTC freq
uint8_t rate = 15;
rate &= 0x0F;
set_interrupts(false);
outb(0x70, 0x8A);
char prev = inb(0x71);
outb(0x70, 0x8A);
outb(0x71, (prev & 0xF0) | rate);
set_interrupts(true);
// Set up RTC periodic interrupts
set_interrupts(false);
outb(0x70, 0x8B);
prev = inb(0x71);
outb(0x70, 0x8B);
outb(0x71, prev | 0x44);
set_interrupts(true);
// Change to binary date format ^^
// Clear IRQ 8 mask
//outb(0xA1, inb(0xA1) & ~(1 << 0));
outb(0xA1, ~(1 << 0));
outb(0x21, ~(1 << 2));
outb(0x70, 0x0C);
unsigned short v = inb(0x71);
terminal_newline();
display_date();
__asm__("int $21");
__asm__("int $10");
__asm__("int $9");
}

0
linker.ld → source/linker.ld Normal file → Executable file
View File

83
print.h → source/print.h Normal file → Executable file
View File

@ -2,6 +2,10 @@
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
#define NORMAL_MODE 0
#define FORMAT_MODE 1
/*
* Hardware text mode color constants.
@ -78,8 +82,23 @@ void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
terminal_buffer[index] = vga_entry(c, color);
}
void terminal_putchar(char);
void terminal_newline()
{
for (size_t x = terminal_column; x < VGA_WIDTH; x++)
{
terminal_putchar(' ');
}
}
void terminal_putchar(char c)
{
if (c == '\n')
{
terminal_newline();
return;
}
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH)
{
@ -127,27 +146,12 @@ void terminal_putchar(char c)
terminal_color = prevColor;
}
void terminal_newline()
{
for (size_t x = terminal_column; x < VGA_WIDTH; x++)
{
terminal_putchar(' ');
}
}
void terminal_write(const char *data, size_t size)
{
for (size_t i = 0; i < size; i++)
{
if (data[i] == '\n')
{
terminal_newline();
}
else
{
terminal_putchar(data[i]);
}
}
}
// Pad length is what number length should be, including padding
@ -257,3 +261,52 @@ void print_texts()
terminal_writestring(" MiB\n");
}
void printf(const char *format, ...)
{
int current_mode = NORMAL_MODE;
va_list vl;
va_start(vl, format);
for (int i = 0; format[i] != '\0'; i++)
{
char current = format[i];
switch (current)
{
case '%':
if (current_mode == FORMAT_MODE)
{
current_mode = NORMAL_MODE;
terminal_putchar(current);
}
else if (current_mode == NORMAL_MODE)
{
current_mode = FORMAT_MODE;
}
break;
default:
if (current_mode == NORMAL_MODE)
{
terminal_putchar(current);
}
else if (current_mode == FORMAT_MODE)
{
// Print argument
switch (current)
{
case 's':
terminal_writestring(va_arg(vl, char*));
break;
case 'd':
terminal_writenum(va_arg(vl, int), 10);
break;
case 'x':
terminal_writenum(va_arg(vl, int), 16);
}
current_mode = NORMAL_MODE;
}
break;
}
}
va_end(vl);
}

78
kernel.c → source/utils.h Normal file → Executable file
View File

@ -1,9 +1,4 @@
#include <stddef.h>
#include <stdint.h>
#include "gdt.h"
#include "print.h"
#include "idt.h"
#pragma once
/* Taken from OSDEV WIKI */
#define PIC1 0x20 /* IO base address for master PIC */
@ -74,6 +69,13 @@ static inline void io_wait(void)
outb(0x80, 0);
}
uint8_t cmos_register_value(uint16_t register_number)
{
outb(0x70, register_number);
return inb(0x71);
}
void PIC_remap(int offset1, int offset2)
{
unsigned char a1, a2;
@ -103,12 +105,6 @@ void PIC_remap(int offset1, int offset2)
outb(PIC2_DATA, a2);
}
uint8_t cmos_register_value(uint16_t register_number)
{
outb(0x70, register_number);
return inb(0x71);
}
void display_date()
{
uint8_t year = cmos_register_value(0x09);
@ -129,61 +125,5 @@ void display_date()
terminal_writenumpad(minutes, 10, 2);
terminal_writestring(":");
terminal_writenumpad(seconds, 10, 2);
}
void kernel_main(void)
{
terminal_initialize();
print_texts();
gdt_setup();
idt_setup();
PIC_remap(0x08, 0x70);
// Set RTC freq
uint8_t rate = 15;
rate &= 0x0F;
set_interrupts(false);
outb(0x70, 0x8A);
char prev = inb(0x71);
outb(0x70, 0x8A);
outb(0x71, (prev & 0xF0) | rate);
set_interrupts(true);
// Set up RTC periodic interrupts
set_interrupts(false);
outb(0x70, 0x8B);
prev = inb(0x71);
outb(0x70, 0x8B);
outb(0x71, prev | 0x44);
set_interrupts(true);
// Change to binary date format ^^
// Clear IRQ 8 mask
//outb(0xA1, inb(0xA1) & ~(1 << 0));
outb(0xA1, ~(1 << 0));
outb(0x21, ~(1 << 2));
uint8_t slave_mask = inb(0xA1);
terminal_newline();
terminal_writestring("Slave mask: \n");
terminal_writenumpad(slave_mask, 2, 8);
uint8_t master_mask = inb(0x21);
terminal_newline();
terminal_writestring("Master mask:\n");
terminal_writenumpad(master_mask, 2, 8);
outb(0x70, 0x0C);
unsigned short v = inb(0x71);
terminal_newline();
terminal_writenumpad(v, 16, 2);
terminal_newline();
terminal_writestring("PTR");
terminal_writenumpad((uintptr_t)&kernel_main, 16, 16);
terminal_newline();
display_date();
breakpoint();
terminal_newline();
}