kernel

hobby kernel
git clone git://git.evenfri.duckdns.org/kernel.git
Log | Files | Refs | README | LICENSE

commit 97ff1cf15e62e17652fbd4b789e7c07f711c155b
parent 706e95f994b9d474d9a784683273b55a63c24b2f
Author: evenfri <evenfri256@gmail.com>
Date:   Mon,  3 Aug 2026 01:41:33 +0800

feat: pit

Diffstat:
Mdat.h | 5+++++
Mfns.h | 4++++
Midt.c | 16+++++++---------
Minit.c | 5+++++
Aisr_stub.asm | 25+++++++++++++++++++++++++
Mmkfile | 2++
Apit.c | 36++++++++++++++++++++++++++++++++++++
7 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/dat.h b/dat.h @@ -66,4 +66,9 @@ typedef void (*int_handler)(); #define sys_read 0 #define sys_write 1 +/* pit */ +#define pit_chan0 0x40 +#define pit_comm 0x43 +#define pit_base_freq 1193182 + #endif /* dat_h */ diff --git a/fns.h b/fns.h @@ -60,4 +60,8 @@ size_t vfs_write(unsigned int fd, void *buf, size_t size); /* syscall */ void syscall_init(); +/* pit */ +void pit_init(uint32_t freq); +void pit_sleep(uint32_t ticks_to_wait); + #endif /* fns_h */ diff --git a/idt.c b/idt.c @@ -22,10 +22,8 @@ void pic_remap() { outb(pic_1_data, 0x01); io_wait(); outb(pic_2_data, 0x01); io_wait(); - outb(pic_1_data, 0b11111101); io_wait(); + outb(pic_1_data, 0xFC); io_wait(); outb(pic_2_data, 0xff); io_wait(); - - asm volatile ("sti"); } void idt_load() { @@ -36,8 +34,6 @@ void idt_load() { } void idt_register(unsigned char vec, int_handler handler) { - asm volatile ("cli"); - unsigned int addr = (unsigned int) handler; idt[vec].isr_low = addr & 0xffff; @@ -45,12 +41,14 @@ void idt_register(unsigned char vec, int_handler handler) { idt[vec].reserved = 0; idt[vec].attr = 0x8e; idt[vec].isr_high = addr >> 16; - - idt_load(); - - asm volatile ("sti"); } void idt_init(void) { + asm volatile ("cli"); + for (int i = 0; i < 256; i++) { + idt_register(i, excp_handler); + } + pic_remap(); + idt_load(); } diff --git a/init.c b/init.c @@ -21,12 +21,17 @@ void init() { idt_init(); vfs_write(stdout, "idt initialized\n", 16); + + pit_init(1000); + vfs_write(stdout, "pit initialized (freq = 1000)\n", 30); syscall_init(); vfs_write(stdout, "syscalls initialized\n", 21); keyboard_init(); vfs_write(stdout, "keyboard initialized\n", 21); + + asm volatile ("sti"); } void bin_init_prog() { diff --git a/isr_stub.asm b/isr_stub.asm @@ -0,0 +1,25 @@ +bits 32 + +global irq0_stub +extern pit_handler + +section .text + +irq0_stub: + pusha + + mov ax, ds + push eax + + mov ax, 0x10 + mov ds, ax + mov es, ax + + call pit_handler + + pop eax + mov ds, ax + mov es, ax + + popa + iret diff --git a/mkfile b/mkfile @@ -14,11 +14,13 @@ ofiles = boot.$o \ vga.$o \ gdt.$o \ idt.$o \ + isr_stub.$o \ ints.$o \ tty.$o \ vfs.$o \ syscall_entry.$o \ syscall.$o \ + pit.$o \ init.$o \ strlen.$o diff --git a/pit.c b/pit.c @@ -0,0 +1,36 @@ +#include <dat.h> +#include <fns.h> + +volatile uint64_t g_ticks = 0; + +extern void irq0_stub(void); + +void pit_handler(void) { + g_ticks++; + outb(0x20, 0x20); +} + +void pit_init(uint32_t freq) { + /* calc divisor */ + uint32_t divisor = pit_base_freq / freq; + + /* limit */ + if (divisor > 0xffff) divisor = 0xffff; + if (divisor < 1) divisor = 1; + + /* command byte */ + outb(pit_comm, 0x36); + /* lsb */ + outb(pit_chan0, (uint8_t)(divisor & 0xff)); + /* msb */ + outb(pit_chan0, (uint8_t)((divisor >> 8) & 0xff)); + + idt_register(0x20, irq0_stub); +} + +void pit_sleep(uint32_t ticks_to_wait) { + uint64_t target_ticks = g_ticks + ticks_to_wait; + while (g_ticks < target_ticks) { + asm volatile ("hlt"); + } +}