mirror of
https://github.com/originalmk/mkos32.git
synced 2024-11-20 09:08:50 +00:00
Reorganised files into directories
This commit is contained in:
parent
ccd3538d1f
commit
226ad82b29
1
.gitignore
vendored
Normal file → Executable file
1
.gitignore
vendored
Normal file → Executable file
@ -5,3 +5,4 @@ mkos.bin
|
|||||||
mkos.iso
|
mkos.iso
|
||||||
bx_enh_dbg.ini
|
bx_enh_dbg.ini
|
||||||
dysk.img
|
dysk.img
|
||||||
|
.idea/
|
||||||
|
@ -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
4
bochsrc → config/bochsrc
Normal file → Executable file
@ -1,9 +1,9 @@
|
|||||||
megs: 32
|
megs: 32
|
||||||
cpu: count=1, ips=9000000
|
cpu: count=1, ips=9000000
|
||||||
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
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: 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
|
boot: cdrom
|
||||||
display_library: x, options="gui_debug"
|
display_library: x, options="gui_debug"
|
||||||
magic_break: enabled=1
|
magic_break: enabled=1
|
0
grub.cfg → config/grub.cfg
Normal file → Executable file
0
grub.cfg → config/grub.cfg
Normal file → Executable file
122
idt.h
122
idt.h
@ -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");
|
|
||||||
}
|
|
@ -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
4
scripts/compile.sh
Executable 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
|
@ -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
4
scripts/makeiso.sh
Executable 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
|
@ -2,5 +2,5 @@
|
|||||||
./compile.sh
|
./compile.sh
|
||||||
./makeiso.sh
|
./makeiso.sh
|
||||||
# Remove lock in case of bad shutdown, it makes debugging easier
|
# Remove lock in case of bad shutdown, it makes debugging easier
|
||||||
rm dysk.img.lock
|
rm ../filesystem/dysk.img.lock
|
||||||
bochs
|
bochs -f ../config/bochsrc
|
114
boot.s → source/boot.s
Normal file → Executable file
114
boot.s → source/boot.s
Normal file → Executable file
@ -32,7 +32,7 @@
|
|||||||
.global stack_top
|
.global stack_top
|
||||||
.global stack_bottom
|
.global stack_bottom
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
/* Stos o wielkości 16 KB */
|
/* Stos o wielkości 64 KB */
|
||||||
.skip 65536
|
.skip 65536
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
@ -45,83 +45,55 @@ clock_pos: .int 0x0
|
|||||||
Oznaczenie startu, tu zaczyna się kod kernela!
|
Oznaczenie startu, tu zaczyna się kod kernela!
|
||||||
*/
|
*/
|
||||||
.section .text
|
.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
|
call isr_common_handler
|
||||||
jne end
|
|
||||||
|
|
||||||
movl $0x0, int_count
|
add $4, %esp
|
||||||
|
|
||||||
end:
|
popa
|
||||||
xchg %bx, %bx
|
|
||||||
|
|
||||||
mov $0x20, %al
|
|
||||||
outb %al, $0x20
|
|
||||||
|
|
||||||
mov $0x20, %al
|
|
||||||
outb %al, $0xA0
|
|
||||||
|
|
||||||
pop %eax
|
|
||||||
sti
|
sti
|
||||||
iretl
|
iretl
|
||||||
|
.endm
|
||||||
|
|
||||||
.global clock_isr
|
isr 0
|
||||||
.type clock_isr, @function
|
isr 1
|
||||||
clock_isr:
|
isr 2
|
||||||
cli
|
isr 3
|
||||||
push %eax
|
isr 4
|
||||||
|
isr 5
|
||||||
//xchg %bx, %bx
|
isr 6
|
||||||
|
isr 7
|
||||||
mov $0x0F41, %ax
|
isr 8
|
||||||
add clock_count, %ax
|
isr 9
|
||||||
mov clock_pos, %edx
|
isr 10
|
||||||
shl $1, %edx
|
isr 11
|
||||||
add $0xb8002, %edx
|
isr 12
|
||||||
movw %ax, (%edx)
|
isr 13
|
||||||
|
isr 14
|
||||||
incl clock_count
|
isr 15
|
||||||
|
isr 16
|
||||||
cmpl $0x1F, clock_count
|
isr 17
|
||||||
jne end2
|
isr 18
|
||||||
|
isr 19
|
||||||
movl $0x0, clock_count
|
isr 20
|
||||||
|
isr 21
|
||||||
end2:
|
isr 22
|
||||||
|
isr 23
|
||||||
incl clock_pos
|
isr 24
|
||||||
cmpl $0x7CF, clock_pos
|
isr 25
|
||||||
jne end3
|
isr 26
|
||||||
|
isr 27
|
||||||
movl $0x0, clock_pos
|
isr 28
|
||||||
|
isr 29
|
||||||
end3:
|
isr 30
|
||||||
|
isr 31
|
||||||
//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
|
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.type _start, @function
|
0
gdt.h → source/gdt.h
Normal file → Executable file
0
gdt.h → source/gdt.h
Normal file → Executable file
210
source/idt.h
Executable file
210
source/idt.h
Executable 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
53
source/kernel.c
Executable 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
0
linker.ld → source/linker.ld
Normal file → Executable file
83
print.h → source/print.h
Normal file → Executable file
83
print.h → source/print.h
Normal file → Executable file
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define NORMAL_MODE 0
|
||||||
|
#define FORMAT_MODE 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hardware text mode color constants.
|
* 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);
|
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)
|
void terminal_putchar(char c)
|
||||||
{
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
terminal_newline();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
|
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
|
||||||
if (++terminal_column == VGA_WIDTH)
|
if (++terminal_column == VGA_WIDTH)
|
||||||
{
|
{
|
||||||
@ -127,27 +146,12 @@ void terminal_putchar(char c)
|
|||||||
terminal_color = prevColor;
|
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)
|
void terminal_write(const char *data, size_t size)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
{
|
|
||||||
if (data[i] == '\n')
|
|
||||||
{
|
|
||||||
terminal_newline();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
terminal_putchar(data[i]);
|
terminal_putchar(data[i]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad length is what number length should be, including padding
|
// Pad length is what number length should be, including padding
|
||||||
@ -257,3 +261,52 @@ void print_texts()
|
|||||||
terminal_writestring(" MiB\n");
|
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
78
kernel.c → source/utils.h
Normal file → Executable file
@ -1,9 +1,4 @@
|
|||||||
#include <stddef.h>
|
#pragma once
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "gdt.h"
|
|
||||||
#include "print.h"
|
|
||||||
#include "idt.h"
|
|
||||||
|
|
||||||
/* Taken from OSDEV WIKI */
|
/* Taken from OSDEV WIKI */
|
||||||
#define PIC1 0x20 /* IO base address for master PIC */
|
#define PIC1 0x20 /* IO base address for master PIC */
|
||||||
@ -74,6 +69,13 @@ static inline void io_wait(void)
|
|||||||
outb(0x80, 0);
|
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)
|
void PIC_remap(int offset1, int offset2)
|
||||||
{
|
{
|
||||||
unsigned char a1, a2;
|
unsigned char a1, a2;
|
||||||
@ -103,12 +105,6 @@ void PIC_remap(int offset1, int offset2)
|
|||||||
outb(PIC2_DATA, a2);
|
outb(PIC2_DATA, a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cmos_register_value(uint16_t register_number)
|
|
||||||
{
|
|
||||||
outb(0x70, register_number);
|
|
||||||
return inb(0x71);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display_date()
|
void display_date()
|
||||||
{
|
{
|
||||||
uint8_t year = cmos_register_value(0x09);
|
uint8_t year = cmos_register_value(0x09);
|
||||||
@ -129,61 +125,5 @@ void display_date()
|
|||||||
terminal_writenumpad(minutes, 10, 2);
|
terminal_writenumpad(minutes, 10, 2);
|
||||||
terminal_writestring(":");
|
terminal_writestring(":");
|
||||||
terminal_writenumpad(seconds, 10, 2);
|
terminal_writenumpad(seconds, 10, 2);
|
||||||
}
|
terminal_newline();
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user