diff --git a/kernel/Makefile b/kernel/Makefile index dbd250f9..88835477 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -69,6 +69,9 @@ apu_boot.o: smp/apu_boot.S cpu.o: common/cpu.c gcc $(CFLAGS) -c common/cpu.c -o common/cpu.o +softirq.o: exception/softirq.c + gcc $(CFLAGS) -c exception/softirq.c -o exception/softirq.o + # IPI的代码 ifeq ($(ARCH), x86_64) OBJ_LIST += ipi.o @@ -115,16 +118,19 @@ rtc.o: driver/timers/rtc/rtc.c HPET.o: driver/timers/HPET/HPET.c gcc $(CFLAGS) -c driver/timers/HPET/HPET.c -o driver/timers/HPET/HPET.o +timer.o: driver/timers/timer.c + gcc $(CFLAGS) -c driver/timers/timer.c -o driver/timers/timer.o + all: kernel objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf # -kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o $(OBJ_LIST) +kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o $(OBJ_LIST) ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \ - common/cpu.o smp/smp.o smp/apu_boot.o \ - driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o \ + common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o \ + driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \ $(LD_LIST) \ -T link.lds diff --git a/kernel/common/glib.h b/kernel/common/glib.h index ff7a4b73..2d5447e6 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -393,3 +393,14 @@ ul rdmsr(ul address) : "memory"); return ((ul)tmp0 << 32) | tmp1; } + + +uint64_t get_rflags() +{ + unsigned long tmp = 0; + __asm__ __volatile__ ("pushfq \n\t" + "movq (%%rsp), %0 \n\t" + "popfq \n\t" + :"=r"(tmp)::"memory"); + return tmp; +} \ No newline at end of file diff --git a/kernel/common/printk.c b/kernel/common/printk.c index a71affaf..fe100507 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -36,10 +36,9 @@ int printk_init(const int char_size_x, const int char_size_y) pos.max_x = calculate_max_charNum(pos.width, char_size_x); pos.max_y = calculate_max_charNum(pos.height, char_size_y); - VBE_FB_phys_addr = (ul)info.framebuffer_addr; pos.FB_address = (uint *)0x0000000003000000; - pos.FB_length = 1UL*pos.width * pos.height; + pos.FB_length = 1UL * pos.width * pos.height; // 初始化自旋锁 spin_init(&printk_lock); @@ -75,9 +74,7 @@ int printk_init(const int char_size_x, const int char_size_y) kdebug("width=%d\theight=%d", pos.width, pos.height); - while (1) - - return 0; + return 0; } int set_printk_pos(const int x, const int y) @@ -120,7 +117,7 @@ void auto_newline() pos.y = pos.max_y; int lines_to_scroll = 1; scroll(true, lines_to_scroll * pos.char_size_y, false); - pos.y -= (lines_to_scroll-1); + pos.y -= (lines_to_scroll - 1); } } @@ -654,8 +651,11 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, .. * @param BKcolor 背景色 * @param ... 格式化字符串 */ - - spin_lock(&printk_lock); + + /* + if (get_rflags() & 0x200UL) + spin_lock(&printk_lock); // 不是中断处理程序调用printk,加锁 + */ va_list args; va_start(args, fmt); @@ -712,8 +712,10 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, .. } } - for(int j=0;j<1e5;++j); - spin_unlock(&printk_lock); + /* + if (get_rflags() & 0x200UL) + spin_unlock(&printk_lock); + */ return i; } diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index aafd0e28..096575c2 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -6,6 +6,8 @@ #include "../../../exception/gate.h" #include "../../acpi/acpi.h" +#include + // 导出定义在irq.c中的中段门表 extern void (*interrupt_table[24])(void); @@ -389,9 +391,9 @@ void apic_local_apic_init() */ void apic_init() { - // 初始化中断门, 中断使用第二个ist + // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉 for (int i = 32; i <= 55; ++i) - set_intr_gate(i, 2, interrupt_table[i - 32]); + set_intr_gate(i, 0, interrupt_table[i - 32]); // 初始化主芯片 io_out8(0x20, 0x11); // 初始化主芯片的icw1 io_out8(0x21, 0x20); // 设置主芯片的中断向量号为0x20(0x20-0x27) @@ -466,6 +468,10 @@ void do_IRQ(struct pt_regs *rsp, ul number) kwarn("do IRQ receive: %d", number); break; } + + // 检测是否有未处理的软中断 + if (softirq_status != 0) + do_softirq(); } /** diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index 1933f73b..8ed8bf86 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include static struct acpi_HPET_description_table_t *hpet_table; static uint64_t HPET_REG_BASE = 0; @@ -46,14 +48,15 @@ hardware_intr_controller HPET_intr_controller = void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { - //printk_color(ORANGE, BLACK, "(HPET)"); switch (param) { - case 0: - rtc_get_cmos_time(&rtc_now); + case 0: // 定时器0中断 + ++timer_jiffies; + set_softirq_status(TIMER_SIRQ); break; default: + kwarn("Unsupported HPET irq: %d.", number); break; } } @@ -97,6 +100,4 @@ int HPET_init() rtc_get_cmos_time(&rtc_now); *(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0; io_mfence(); - - } \ No newline at end of file diff --git a/kernel/driver/timers/rtc/rtc.h b/kernel/driver/timers/rtc/rtc.h index 244f0a9a..2adb1670 100644 --- a/kernel/driver/timers/rtc/rtc.h +++ b/kernel/driver/timers/rtc/rtc.h @@ -16,4 +16,6 @@ struct rtc_time_t * @param t time结构体 * @return int 成功则为0 */ -int rtc_get_cmos_time(struct rtc_time_t*t); \ No newline at end of file +int rtc_get_cmos_time(struct rtc_time_t*t); + +void rtc_init(); \ No newline at end of file diff --git a/kernel/driver/timers/timer.c b/kernel/driver/timers/timer.c new file mode 100644 index 00000000..af674634 --- /dev/null +++ b/kernel/driver/timers/timer.c @@ -0,0 +1,14 @@ +#include "timer.h" +#include +#include + +void timer_init() +{ + timer_jiffies = 0; + register_softirq(0, &do_timer_softirq, NULL); +} + +void do_timer_softirq(void* data) +{ + printk_color(ORANGE, BLACK, "(HPET%ld)", timer_jiffies); +} \ No newline at end of file diff --git a/kernel/driver/timers/timer.h b/kernel/driver/timers/timer.h new file mode 100644 index 00000000..5a94fb66 --- /dev/null +++ b/kernel/driver/timers/timer.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include "HPET/HPET.h" +#include "rtc/rtc.h" + +uint64_t volatile timer_jiffies = 0; // 系统时钟计数 + +void timer_init(); + +void do_timer_softirq(void* data); \ No newline at end of file diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index 9d70d1e3..c3938d0c 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -50,7 +50,6 @@ Restore_all: popq %rax addq $0x10, %rsp // 弹出变量FUNC和errcode - iretq ret_from_exception: @@ -58,6 +57,7 @@ ret_from_exception: ENTRY(ret_from_intr) jmp Restore_all + Err_Code: // ===== 有错误码的情况下,保存寄存器并跳转服务程序 diff --git a/kernel/exception/softirq.c b/kernel/exception/softirq.c new file mode 100644 index 00000000..f40373ea --- /dev/null +++ b/kernel/exception/softirq.c @@ -0,0 +1,65 @@ +#include "softirq.h" +#include + +void set_softirq_status(uint64_t status) +{ + softirq_status |= status; +} + +uint64_t get_softirq_status() +{ + return softirq_status; +} + +/** + * @brief 软中断注册函数 + * + * @param irq_num 软中断号 + * @param action 响应函数 + * @param data 响应数据结构体 + */ +void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data) +{ + softirq_vector[irq_num].action = action; + softirq_vector[irq_num].data = data; +} + +/** + * @brief 卸载软中断 + * + * @param irq_num 软中断号 + */ +void unregister_softirq(uint32_t irq_num) +{ + softirq_vector[irq_num].action = NULL; + softirq_vector[irq_num].data = NULL; +} + +/** + * @brief 软中断处理程序 + * + */ +void do_softirq() +{ + + sti(); + for(uint32_t i=0;i + +#define MAX_SOFTIRQ_NUM 64 + +#define TIMER_SIRQ (1<<0) // 时钟软中断号 + +uint64_t softirq_status = 0; + +struct softirq_t +{ + void (*action)(void* data); // 软中断处理函数 + void* data; +}; + +struct softirq_t softirq_vector[MAX_SOFTIRQ_NUM] = {0}; + + +/** + * @brief 软中断注册函数 + * + * @param irq_num 软中断号 + * @param action 响应函数 + * @param data 响应数据结构体 + */ +void register_softirq(uint32_t irq_num, void (*action)(void * data), void* data); + +/** + * @brief 卸载软中断 + * + * @param irq_num 软中断号 + */ +void unregister_softirq(uint32_t irq_num); + +void set_softirq_status(uint64_t status); +uint64_t get_softirq_status(); + +/** + * @brief 软中断处理程序 + * + */ +void do_softirq(); + + +void softirq_init(); \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c index 46d2a2be..49b1ce57 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -8,6 +8,7 @@ #include "exception/gate.h" #include "exception/trap.h" #include "exception/irq.h" +#include #include "mm/mm.h" #include "mm/slab.h" #include "process/process.h" @@ -24,6 +25,7 @@ #include "driver/disk/ahci/ahci.h" #include #include +#include unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址 @@ -167,9 +169,9 @@ void system_initialize() acpi_init(); // 初始化中断模块 irq_init(); - + softirq_init(); + timer_init(); HPET_init(); - smp_init(); // 先初始化系统调用模块 @@ -181,7 +183,6 @@ void system_initialize() // ata_init(); pci_init(); ahci_init(); - // test_slab(); // test_mm(); @@ -233,6 +234,7 @@ void Start_Kernel(void) // ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0xc8, ICR_APIC_FIXED, ICR_No_Shorthand, true, 1); // 测试ipi int last_sec = rtc_now.second; + /* while (1) { if (last_sec != rtc_now.second) @@ -241,6 +243,7 @@ void Start_Kernel(void) kinfo("Current Time: %04d/%02d/%02d %02d:%02d:%02d", rtc_now.year, rtc_now.month, rtc_now.day, rtc_now.hour, rtc_now.minute, rtc_now.second); } } + */ while (1) hlt(); }