]> Zhao Yanbai Git Server - kernel.git/commitdiff
添加disk测试逻辑
authoracevest <zhaoyanbai@126.com>
Sun, 21 May 2023 15:11:28 +0000 (23:11 +0800)
committeracevest <zhaoyanbai@126.com>
Sun, 21 May 2023 15:11:28 +0000 (23:11 +0800)
drivers/ata.c
drivers/ide.c
include/printk.h
kernel/irq.c
kernel/sched.c
kernel/task_disk.c
kernel/task_root.c
qemu.sh

index b9f167db3873c59153a70559226170d9b38fff0f..dc258aa2a857e1dc03ffea37a4e87a13a3de804e 100644 (file)
@@ -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
index ed188e79da423988151132ab6a917969e5f40fae..04d0b61da48281397bac21f294f9381b25bf9f5a 100644 (file)
@@ -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;
index bc04ce6eaea7c63cf33370683707fc37be87cd44..e60bf5b65a87a5017a9ea6076e9b8fa33752cb6f 100644 (file)
@@ -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,
index a7a89d9624cbe3e0e20d9c1e32177396c598ce3b..073ee2ce20fa69feaa398ceb4854437a40c3b539 100644 (file)
@@ -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);
index 9a7e214132ba897d84304e07e9209179de362550..c97b1ea5cd0a3f9711e49b43abdc25a076185785 100644 (file)
@@ -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;
         }
index fc85b5c745d071577e5594588df580297346195b..2b94b1c5fb1e36ec2d6878bae08a7fe8e97a2023 100644 (file)
@@ -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;
index 967413838b3de0349a41f2f49af23ba3211e2a6d..13835b7dc09eaca22c083b355881e4460fe6ffe0 100644 (file)
@@ -7,6 +7,7 @@
  * ------------------------------------------------------------------------
  */
 
+#include <disk.h>
 #include <fcntl.h>
 #include <io.h>
 #include <irq.h>
@@ -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 4f7cb2c3d5d301b64296dfc23ae43b4470d90027..c38b3f5dd7cd075204abf5b64994d81bff04d4df 100755 (executable)
--- 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 \
     &