From 7892610058b03350756440b0ebcfa5073415d7c9 Mon Sep 17 00:00:00 2001 From: acevest Date: Sun, 21 May 2023 23:11:28 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0disk=E6=B5=8B=E8=AF=95?= =?utf8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/ata.c | 6 ++-- drivers/ide.c | 3 ++ include/printk.h | 3 +- kernel/irq.c | 2 +- kernel/sched.c | 14 +++++++++ kernel/task_disk.c | 4 +++ kernel/task_root.c | 78 +++++++++++++++++++++++++++++++++++++++++++--- qemu.sh | 1 + 8 files changed, 101 insertions(+), 10 deletions(-) diff --git a/drivers/ata.c b/drivers/ata.c index b9f167d..dc258aa 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -220,8 +220,8 @@ void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) { // by writing a 0 to this bit. This results in all state information being lost (i.e., master mode // operation cannot be stopped and then resumed). - // 停止DMA,并设置为读(这里的WRITE是对DMA控制器来说) - outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_STOP, ide_pci_controller.bus_cmd); + // 停止DMA + outb(PCI_IDE_CMD_STOP, ide_pci_controller.bus_cmd); // 配置描述符表 unsigned long dest_paddr = va2pa(dest); @@ -282,7 +282,7 @@ void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) { // 指定DMA操作为读取硬盘操作,内核用DMA读取,对硬盘而言是写出 // 并设置DMA的开始位,开始DMA - outb(PCI_IDE_CMD_START, ide_pci_controller.bus_cmd); + outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, ide_pci_controller.bus_cmd); } // TODO diff --git a/drivers/ide.c b/drivers/ide.c index ed188e7..04d0b61 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -553,12 +553,15 @@ extern void *mbr_buf; uint8_t ata_pci_bus_status(); extern ide_pci_controller_t ide_pci_controller; +volatile uint32_t disk_inter_cnt = 0; + void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) { // printk("ide irq handler %d \n", irq); printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status()); #if 1 + disk_inter_cnt++; up(&disk_intr_sem); #else ide_pci_controller.done = 1; diff --git a/include/printk.h b/include/printk.h index bc04ce6..e60bf5b 100644 --- a/include/printk.h +++ b/include/printk.h @@ -32,8 +32,9 @@ enum { MPL_KEYBOARD, MPL_IDE, MPL_IDE_INTR, - MPL_PREEMPT, + MPL_CURRENT, MPL_TEST, + MPL_X, MPL_DEBUG, MPL_ROOT, MPL_TASK_0, diff --git a/kernel/irq.c b/kernel/irq.c index a7a89d9..073ee2c 100644 --- a/kernel/irq.c +++ b/kernel/irq.c @@ -57,7 +57,7 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) { unsigned long esp; asm("movl %%esp, %%eax" : "=a"(esp)); - printl(MPL_PREEMPT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp); + printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp); while (action && action->handler) { action->handler(irq, regs, action->dev_id); diff --git a/kernel/sched.c b/kernel/sched.c index 9a7e214..c97b1ea 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -158,6 +158,10 @@ static const char *task_state(unsigned int state) { return s[state]; } +extern uint32_t disk_request_cnt; +extern uint32_t disk_handled_cnt; +extern uint32_t disk_inter_cnt; + unsigned long schedule() { task_union *sel = &root_task; task_union *p = 0; @@ -167,10 +171,17 @@ unsigned long schedule() { irq_save(iflags); // printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt); + printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt); + #if 1 bool need_reset_weight = true; list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); + + if (p == &root_task) { + continue; + } + if (p->state != TASK_READY) { continue; } @@ -193,6 +204,9 @@ unsigned long schedule() { list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); + if (p == &root_task) { + continue; + } if (p->state != TASK_READY) { continue; } diff --git a/kernel/task_disk.c b/kernel/task_disk.c index fc85b5c..2b94b1c 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -28,6 +28,8 @@ void disk_init() { semaphore_init(&disk_intr_sem, 0); } +volatile uint32_t disk_request_cnt = 0; +volatile uint32_t disk_handled_cnt = 0; void send_disk_request(disk_request_t *r) { if (NULL == r) { panic("null disk request"); @@ -47,6 +49,7 @@ void send_disk_request(disk_request_t *r) { #if 1 mutex_lock(&disk_request_mutex); + disk_request_cnt++; list_add_tail(&r->list, &disk_request_queue.list); mutex_unlock(&disk_request_mutex); #else @@ -80,6 +83,7 @@ void disk_task_entry() { } list_del(&r->list); + disk_handled_cnt++; mutex_unlock(&disk_request_mutex); #else unsigned long flags; diff --git a/kernel/task_root.c b/kernel/task_root.c index 9674138..13835b7 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -7,6 +7,7 @@ * ------------------------------------------------------------------------ */ +#include #include #include #include @@ -47,13 +48,66 @@ void kernel_task(char *name, void *entry) { printk("kernel[%s] task pid is %d\n", name, pid); } +// 测试用的代码 +// 这里存的是下标对应的每个扇区的最后2个字节 +// hexdump -C HD.IMG | less 看的,如果镜像文件有变动需要更新这里 +uint16_t hd_sect_data_fingerprint[] = { + 0xAA55, // 0 + 0x0820, // 1 + 0x4d89, // 2 + 0xeb1d, // 3 + 0x1009 // 4 +}; + +uint64_t debug_sect_nr = 0; + +uint64_t get_next_deubug_sect_nr() { + debug_sect_nr++; +#if 0 + debug_sect_nr %= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t); +#else + if (debug_sect_nr >= sizeof(hd_sect_data_fingerprint) / sizeof(uint16_t)) { + debug_sect_nr = 0; + } +#endif + return debug_sect_nr; +} + +void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) { + uint16_t vfp = hd_sect_data_fingerprint[sect_nr]; + + uint16_t fp = buf[255]; + + if (fp == vfp) { + printk("%s verification passed sect %lu fp %04x\n", name, sect_nr, fp); + } else { + printk("%s verification failed sect %lu fp %04x right %04x\n", name, sect_nr, fp, vfp); + panic("verify hd data fail"); + } +} + +u16 disk_buf1[256]; +u16 disk_buf2[256]; + void taskA_entry() { current->priority = 99; while (1) { - sysc_wait(600); + sysc_wait(7); + + uint64_t sect_nr = get_next_deubug_sect_nr(); + memset(disk_buf1, 0, 512); + + disk_request_t r; + r.command = DISK_REQ_READ; + r.pos = sect_nr; + r.count = 1; + r.buf = disk_buf1; + send_disk_request(&r); + + verify_hd_data(sect_nr, disk_buf1, current->name); - for (int i = 0; i < 200; i++) { + for (int i = 0; i < 2; i++) { asm("hlt;"); } } @@ -63,9 +117,19 @@ void taskB_entry() { current->priority = 99; while (1) { - sysc_wait(200); - - for (int i = 0; i < 100; i++) { + sysc_wait(10); + + uint64_t sect_nr = get_next_deubug_sect_nr(); + memset(disk_buf2, 0, 512); + disk_request_t r; + r.command = DISK_REQ_READ; + r.pos = sect_nr; + r.count = 1; + r.buf = disk_buf2; + send_disk_request(&r); + verify_hd_data(sect_nr, disk_buf2, current->name); + + for (int i = 0; i < 1; i++) { asm("hlt;"); } } @@ -101,6 +165,10 @@ void root_task_entry() { kernel_task("disk", disk_task_entry); kernel_task("user", user_task_entry); + // for (int i = 0; i < 100; i++) { + // asm("hlt;"); + // } + kernel_task("tskA", taskA_entry); kernel_task("tskB", taskB_entry); kernel_task("tskC", taskC_entry); diff --git a/qemu.sh b/qemu.sh index 4f7cb2c..c38b3f5 100755 --- a/qemu.sh +++ b/qemu.sh @@ -3,6 +3,7 @@ qemu-system-i386 \ -boot d \ -drive file=HD.IMG,format=raw,index=0,media=disk \ -drive file=kernel.iso,index=1,media=cdrom \ + -name kernel \ -s -S \ & -- 2.44.0