From: acevest Date: Sat, 10 Jan 2026 02:15:31 +0000 (+0800) Subject: AP接管KERNEL MONITOR X-Git-Url: http://repos.zhaoyanbai.com/Mou_128.png?a=commitdiff_plain;h=884009507fd61bb93a0767a29b23135062131ecb;p=kernel.git AP接管KERNEL MONITOR --- diff --git a/drivers/ide.c b/drivers/ide.c index 190801f..19ee78b 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -106,15 +106,6 @@ SATA(Serial ATA)于2002年推出后,原有的ATA改名为PATA(并行高 ide_pci_controller_t ide_pci_controller[NR_IDE_CONTROLLER]; void ata_dma_stop(int channel); - -void ide_stat_print(ide_pci_controller_t* ide_ctrl) { - int r = atomic_read(&(ide_ctrl->request_cnt)); - int i = atomic_read(&(ide_ctrl->irq_cnt)); - int c = atomic_read(&(ide_ctrl->consumed_cnt)); - int channel = ide_ctrl->channel; - printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, r, i, c); -} - void ide_irq_bh_handler(void* arg) { int channel = (int)arg; @@ -131,9 +122,6 @@ void ide_irq_bh_handler(void* arg) { // atomic_inc(&ide_ctrl->irq_cnt); - // - ide_stat_print(ide_ctrl); - // 之前这里是用up()来唤醒磁盘任务 // 但在中断的底半处理,不应该切换任务,因为会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务 // 所以就移除了up()里的 schedule() @@ -272,9 +260,6 @@ void init_pci_controller(unsigned int classcode) { pci->intr_line, pci->vendor, pci->device, pci->progif, pci_get_info(pci->classcode, pci->progif)); // printk("found pci vendor %04x device %04x class %04x intr %d progif: %x\n", pci->vendor, pci->device, // pci->classcode, pci->intr_line, pci->progif); - // printl(17, "found pci vendor %04x device %04x class %04x intr %d", pci->vendor, pci->device, - // pci->classcode, - // pci->intr_line); ide_pci_init(pci); // while (1) asm("cli;hlt;"); } diff --git a/drivers/ide.h b/drivers/ide.h index 96e1974..6076a08 100644 --- a/drivers/ide.h +++ b/drivers/ide.h @@ -228,4 +228,3 @@ typedef struct _ide_drive { extern ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT]; ide_drive_t* ide_get_drive(dev_t dev); -void ide_stat_print(ide_pci_controller_t* ide_ctrl); diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 2a3fbb1..2315c4b 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -72,10 +72,9 @@ extern tty_t* const monitor_tty; extern tty_t* const debug_tty; extern void tty_switch_to_next(); +uint64_t kbd_irq_cnt = 0; void kbd_debug(uint8_t scan_code) { - static unsigned long kbd_cnt = 0; - // printl(MPL_KEYBOARD, "keyboard irq: %d scan code %02x", kbd_cnt++, scan_code); - printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %d", scan_code, kbd_cnt++); + kbd_irq_cnt++; if (scan_code == 0x01) { // Esc // reboot(); diff --git a/include/printk.h b/include/printk.h index 0fbe477..90f21e9 100644 --- a/include/printk.h +++ b/include/printk.h @@ -49,8 +49,8 @@ enum { // monitor print offset enum { - MPO_CLOCK = 1, - MPO_HPET = 28, + MPO_HPET = 1, + MPO_AP_CLOCK = 28, MPO_KEYBOARD = 48, MPO_IDE = 1, }; diff --git a/include/system.h b/include/system.h index a328437..b2e9142 100644 --- a/include/system.h +++ b/include/system.h @@ -59,14 +59,6 @@ void* kmalloc(size_t size, gfp_t gfpflags); void* kzalloc(size_t size, gfp_t gfpflags); void kfree(void* addr); -#define panic(msg, ...) \ - do { \ - asm("cli;"); \ - printl(MPL_DEBUG, "PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \ - printk("PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \ - asm("hlt"); \ - } while (0); - extern char etext, edata, end; #define cli() asm volatile("cli") @@ -271,4 +263,11 @@ paddr_t get_rcba_paddr(); #define DISABLE_IDE 1 +#define panic(msg, ...) \ + do { \ + asm("cli;"); \ + printk("PANIC:" msg " %s %s %d\n", ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__); \ + asm("hlt"); \ + } while (0); + #endif //_SYSTEM_H diff --git a/kernel/ap.c b/kernel/ap.c index b866167..cf6ca44 100644 --- a/kernel/ap.c +++ b/kernel/ap.c @@ -169,7 +169,7 @@ void ap_kernel_entry() { hpet_disable(); // 只要不hpet_enable, HPET的计数器就不会启动 - hpet_prepare_calibration(timn, 2 /*hz*/); + hpet_prepare_calibration(timn, 97 /*hz*/); // hpet_enable(); @@ -219,24 +219,28 @@ void ap_kernel_entry() { uint32_t ap_cpuid = lapic->get_lapic_id(); printk("AP CPU id: %d\n", ap_cpuid); - system.ap_cpuid = ap_cpuid; + system.ap_cpuid = ap_cpuid; // 这之后不能再printk了 asm("sti;"); + const char* title = "KERNEL MONITOR"; + printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title); + while (1) { asm("hlt;"); } } -void do_ap_lapic_irq_handler() { - uint8_t* p = (uint8_t*)0xC00B8002; - *p = *p == ' ' ? 'E' : ' '; - system.lapic->write(LAPIC_EOI, 0); +bool ap_ready() { + return system.ap_cpuid != 0; } +uint64_t ap_pit_ticks = 0; void do_ap_pit_irq_handler() { uint8_t* p = (uint8_t*)0xC00B8004; *p = *p == ' ' ? 'R' : ' '; + ap_pit_ticks++; + system.lapic->write(LAPIC_EOI, 0); } @@ -244,6 +248,90 @@ void do_ap_no_irq_handler() { panic("AP unexpected irq\n"); } -bool ap_ready() { - return system.ap_cpuid != 0; +uint64_t ap_lapic_ticks = 0; +void do_ap_lapic_irq_handler() { + uint8_t* p = (uint8_t*)0xC00B8002; + *p = *p == ' ' ? 'E' : ' '; + + // + extern volatile uint64_t jiffies; + extern volatile uint64_t hpet_ticks; // jiffies 和 hpet_ticks 是同一个东西 + printlxy(MPL_IRQ, MPO_HPET, "HPET: %lu", jiffies); + + // + extern volatile uint8_t scan_code; + extern volatile uint64_t kbd_irq_cnt; + printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %lu", scan_code, kbd_irq_cnt); + + // + printlxy(MPL_IRQ, MPO_AP_CLOCK, "AP: %lu", ap_lapic_ticks); + + // + void print_all_tasks(); + print_all_tasks(); + + // + // void print_all_ides(); + // print_all_ides(); + + ap_lapic_ticks++; + + system.lapic->write(LAPIC_EOI, 0); +} + +#include +const char* task_state(unsigned int state) { + static const char s[][8] = { + " ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ", + }; + + if (state >= TASK_END) { + state = TASK_UNUSED; + } + + return s[state]; +} +void print_all_tasks() { + extern task_t* monitor_tasks[]; + + printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN"); + + for (int i = 0; i < 10; i++) { + task_t* p = monitor_tasks[i]; + + if (p == NULL) { + continue; + } + + printl(MPL_TASK_0 + p->pid, "a%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", + p, // + p->name, // + p->pid, // + task_state(p->state), // + p->ticks, // + p->priority, // + p->reason, // + p->sched_cnt, // + p->sched_keep_cnt, // + p->turn // + ); + } +} + +#include +extern ide_pci_controller_t ide_pci_controller[]; +void ide_stat_print(ide_pci_controller_t* ide_ctrl) { + assert(ide_ctrl != NULL); + assert(ide_ctrl >= ide_pci_controller); + assert(ide_ctrl < (ide_pci_controller + NR_IDE_CONTROLLER)); + int r = atomic_read(&(ide_ctrl->request_cnt)); + int i = atomic_read(&(ide_ctrl->irq_cnt)); + int c = atomic_read(&(ide_ctrl->consumed_cnt)); + int channel = ide_ctrl->channel; + printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, r, i, c); +} + +void print_all_ides() { + ide_stat_print(&ide_pci_controller[0]); + ide_stat_print(&ide_pci_controller[1]); } diff --git a/kernel/apic.c b/kernel/apic.c index 7b71419..f0ec955 100644 --- a/kernel/apic.c +++ b/kernel/apic.c @@ -318,6 +318,7 @@ void ioapic_init() { // ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (dst_cpuid << 56)); // 把8253/8254的中断通过IOAPIC转发到CPU1的0号中断 ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56)); + ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56) | 0x10000); // 把键盘中断通过IOAPIC转发到CPU0的1号中断 ioapic_rte_write(IOAPIC_RTE(1), 0x20 + 1 | (dst_cpuid << 56)); // irq_set_chip(0x00, &ioapic_chip); // ap不需要这个 diff --git a/kernel/assert.c b/kernel/assert.c index 34070ff..fa391a0 100644 --- a/kernel/assert.c +++ b/kernel/assert.c @@ -14,7 +14,6 @@ void assert_fail(char* exp, char* file, unsigned int line, const char* func) { asm("cli"); - printl(MPL_DEBUG, "%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp); printk("%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp); while (1) { asm("hlt;"); diff --git a/kernel/clock.c b/kernel/clock.c index efa644f..21fe47a 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -22,20 +22,11 @@ unsigned int sys_clock() { return jiffies; } -void debug_print_all_tasks(); - -void dump_irq_nr_stack(); void clk_bh_handler(void* arg); extern volatile bool enable_clock_irq_delay; void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { - // if (jiffies % 100 == 0) { - // printl(MPL_CLOCK, "clock irq: %d", jiffies); - printlxy(MPL_IRQ, MPO_CLOCK, "CLK: %d", jiffies); - // printk("CLK irq %d\n", jiffies); - // } - jiffies++; current->jiffies = jiffies; diff --git a/kernel/fork.c b/kernel/fork.c index 9562119..b11182b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -13,8 +13,6 @@ #include #include -extern void ret_from_fork_user(); -extern void ret_from_fork_krnl(); extern pid_t get_next_pid(); extern list_head_t all_tasks; @@ -61,36 +59,7 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { continue; } -#if 1 pde_dst[i] = pde_src[i] & (~PDE_RW); -#else - // 这里不用再为每个PDE拷贝一次PageTable,只需要拷贝PageDirectory并将其低于768的写权限去掉 - // 同时需要修改缺页异常do_page_fault的逻辑 - if (PAGE_ALIGN(spde) != 0) { - dpde = page2va(alloc_one_page(0)); - assert(dpde != 0); - memset((void*)dpde, 0, PAGE_SIZE); - dpde = PAGE_FLAGS(spde) | (unsigned long)va2pa(dpde); - } else { - pde_dst[i] = 0; - continue; - } - pde_dst[i] = dpde; - - pte_t* pte_src = pa2va(PAGE_ALIGN(spde)); - pte_t* pte_dst = pa2va(PAGE_ALIGN(dpde)); - for (j = 0; j < PAGE_PTE_CNT; ++j) { - pte_src[j] &= ~PAGE_WR; - pte_dst[j] = pte_src[j]; - - if (pte_src[j] == 0) { - continue; - } - printk("----pde[%u] pte_src[%u] %08x\n", i, j, pte_src[j]); - page_t* page = pa2page(pte_src[j]); - page->count++; - } -#endif } pt_regs_t* child_regs = ((pt_regs_t*)(TASK_SIZE + (unsigned long)tsk)) - 1; @@ -129,6 +98,9 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { tsk->state = TASK_READY; + void add_task_for_monitor(task_t * tsk); + add_task_for_monitor(tsk); + return (int)tsk->pid; fork_child: diff --git a/kernel/hpet.c b/kernel/hpet.c index e115a74..665bf94 100644 --- a/kernel/hpet.c +++ b/kernel/hpet.c @@ -88,19 +88,13 @@ void hpet_disable() { uint32_t hpet_clock_period = 0; uint64_t hpet_clock_mhz_freq = 0; // 32位系统不支持64位除法,所以用MHz为单位 -static uint64_t hpet_ticks = 0; -void hpet0_bh_handler() { - // hpet_ticks++; - printlxy(MPL_IRQ, MPO_HPET, "HPET: %lu", hpet_ticks); -} +uint64_t hpet_ticks = 0; void hpet0_irq_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) { hpet_ticks++; uint8_t* p = (uint8_t*)0xC00B8000; *p = *p == ' ' ? 'K' : ' '; - add_irq_bh_handler(hpet0_bh_handler, NULL); - system.lapic->write(LAPIC_EOI, 0); } diff --git a/kernel/irq.c b/kernel/irq.c index 4137ad5..3525f2d 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -42,34 +42,6 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) { panic("invalid irq %d\n", irq); } -#if 0 - assert(1 == irq); - uint8_t b = inb(0x60); - printk("irq %d b %02x\n", irq, b); - // write_msr32(0x80b, 0); - system.lapic->write(0xB0, 0); - // vaddr_t apic_virt_base_addr = fixid_to_vaddr(FIX_LAPIC_BASE); - // apic_virt_base_addr += 0xB0; - // *((volatile uint32_t*)apic_virt_base_addr) = 0x0; -#endif -#if 0 - // 检查IMCR - outb(0x22, 0x70); - uint8_t imcr = inb(0x23); - printk("IMCR: 0x%02x (bit0=%s, bit1=%s)\n", imcr, (imcr & 0x01) ? "APIC" : "PIC", - (imcr & 0x02) ? "PIC masked" : "PIC active"); - - // 检查8259A状态 - uint8_t pic1_imr = inb(0x21); - uint8_t pic2_imr = inb(0xA1); - printk("8259A IMR: Master=0x%02x, Slave=0x%02x\n", pic1_imr, pic2_imr); - - // 检查IOAPIC是否响应 - volatile uint32_t* ioapic = (volatile uint32_t*)system.ioapic_map->io_reg_sel; - ioapic[0] = 0x01; // 选择版本寄存器 - uint32_t version = ioapic[4]; - printk("IOAPIC version: 0x%08x\n", version); -#endif #if 1 irq_desc_t* p = irq_desc + irq; irq_action_t* action = p->action; @@ -82,16 +54,6 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) { assert(reenter <= 1); // TODO 判断打断的是否是内核态代码 -#if 0 - if (0x00 == irq) { - if ((clk_irq_cnt++ & 0xFU) != 0) { - unsigned long esp; - asm("movl %%esp, %%eax" : "=a"(esp)); - printl(MPL_CURRENT, "current %08x %-6s cr3 %08x reenter %d:%u esp %08x ticks %u", current, current->name, - current->cr3, reenter, reenter_count, esp, current->ticks); - } - } -#endif while (action && action->handler) { action->handler(irq, regs, action->dev_id); @@ -205,15 +167,13 @@ void irq_bh_handler() { // 这里可能存在有部分没处理完 } - void debug_print_all_tasks(); #if ENABLE_CLOCK_IRQ_WAIT - debug_print_all_tasks(); if (irq_bh_actions == NULL) { asm("hlt;"); } #else if (jiffies < end) { - debug_print_all_tasks(); + // debug_print_all_tasks(); } #endif } diff --git a/kernel/ring3.S b/kernel/ring3.S index a187fa8..ba947bd 100644 --- a/kernel/ring3.S +++ b/kernel/ring3.S @@ -42,7 +42,7 @@ ring3_entry: # 纯消耗CPU时间 - movl $0x0F0F0F0F, %ecx + movl $0xFF0F0F0F, %ecx 1: loop 1b diff --git a/kernel/sched.c b/kernel/sched.c index b057077..279ced2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -149,29 +149,6 @@ task_t* find_task(pid_t pid) { return p; } -const char* task_state(unsigned int state) { - static const char s[][8] = { - " ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ", - }; - - if (state >= TASK_END) { - state = TASK_UNUSED; - } - - return s[state]; -} - -void debug_print_all_tasks() { - task_t* p = 0; - list_head_t *pos = 0, *t = 0; - printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN"); - list_for_each_safe(pos, t, &all_tasks) { - p = list_entry(pos, task_t, list); - printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", p, p->name, p->pid, - task_state(p->state), p->ticks, p->priority, p->reason, p->sched_cnt, p->sched_keep_cnt, p->turn); - } -} - void schedule() { task_t* root = &root_task; task_t* sel = 0; @@ -264,3 +241,10 @@ void debug_sched() { task_t* p = list_entry(current->list.next, task_t, list); p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY; } + +task_t* monitor_tasks[1024] = {&root_task, 0}; +void add_task_for_monitor(task_t* tsk) { + assert(tsk != NULL); + int id = tsk->pid; + monitor_tasks[id] = tsk; +} diff --git a/kernel/setup.c b/kernel/setup.c index e3b13d8..544c590 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -144,9 +144,6 @@ void setup_kernel() { cnsl_init(); boot_delay(DEFAULT_BOOT_DELAY_TICKS); - const char* title = "KERNEL MONITOR"; - printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title); - setup_fs(); setup_tasks(); @@ -188,7 +185,7 @@ void setup_kernel() { // ap 启动需要用到 hpet来校准 wait_ap_boot(); - hpet_init_timer0(1); + hpet_init_timer0(101); #if !DISABLE_IDE void ide_init(); diff --git a/kernel/syscall.c b/kernel/syscall.c index 52a76ea..7eab1e8 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -68,7 +68,7 @@ int sysc_pause() { int sysc_debug(unsigned int v) { static unsigned int cnt = 0; - printl(MPL_DEBUG, "task debug syscall %u value %08x", cnt++, v); + cnt++; return 0; } diff --git a/kernel/task_disk.c b/kernel/task_disk.c index 5623a1b..f3ffcfd 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -157,8 +157,6 @@ void disk_task_entry(void* arg) { printk("IDE status %02X error for drv %u pos %lu count %u\n", ide_ctrl->status, drvid, pos, r->count); ret = -1; } - - ide_stat_print(ide_ctrl); } // 读数据