]> Zhao Yanbai Git Server - kernel.git/commitdiff
支持IDE Secondary通道上的硬盘
authoracevest <zhaoyanbai@126.com>
Mon, 5 Jun 2023 04:58:54 +0000 (12:58 +0800)
committeracevest <zhaoyanbai@126.com>
Mon, 5 Jun 2023 04:58:54 +0000 (12:58 +0800)
22 files changed:
Makefile
drivers/ata.c
drivers/ata.h
drivers/ide.c
drivers/ide.h
drivers/keyboard.c
drivers/pci.c
include/disk.h
include/irq.h
include/semaphore.h
include/system.h
kernel/clock.c
kernel/irq.c
kernel/sched.c
kernel/setup.c
kernel/syscall.S
kernel/system.c
kernel/task_disk.c
kernel/task_init.c
kernel/task_root.c
kernel/tty.c
qemu.sh

index 1712475a07162e3e0dad703585e63efb532283f0..db2cf4ec5f513c3b263c6251660bd6aee8cfad43 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ endif
 
 
 CFLAGS         = -g -c -fno-builtin -m32 -DBUILDER='"$(shell whoami)"'
+CFLAGS     += -DNR_TTYS=3
 CFLAGS     += -DFIX_SYSENTER_ESP_MODE=1
 #CFLAGS     += -DENABLE_BOOT_WAIT=1
 SYSTEMMAP      = System.map
index f2db9753c1235f6f4487def7023077499b9928ef..e7422e116f303aa001453afa9e99ca2b9978e95d 100644 (file)
 #include <string.h>
 #include <system.h>
 
-extern ide_pci_controller_t ide_pci_controller;
+extern ide_pci_controller_t ide_pci_controller[];
 
-typedef struct _ide_drive {
-    int present;
-    int dma;
-    uint64_t lba48;
-    uint64_t max_lba;
-} ide_drive_t;
-
-#define MAX_IDE_DRIVE_CNT 4
 ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT];
 
 #define ATA_TIMEOUT 10  // 10次时钟中断
 
-void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest);
-int ata_pio_read_ext(int dev, uint64_t pos, uint16_t count, int timeout, void *dest);
+void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest);
+int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count, int timeout, void *dest);
 
 void *mbr_buf;
 void ata_test(uint64_t nr) {
@@ -53,19 +45,19 @@ void ata_test(uint64_t nr) {
 //  2. 等到status的BSY位清除
 //  3. 等到status的DRQ位或ERR位设置
 u16 identify[256];
-void ata_send_read_identify_cmd(int dev) {}
+void ata_send_read_identify_cmd(int drv) {}
 
-void ata_read_data(int dev, int sect_cnt, void *dst) { insl(REG_DATA(dev), dst, (512 * sect_cnt) / sizeof(uint32_t)); }
+void ata_read_data(int drv, int sect_cnt, void *dst) { insl(REG_DATA(drv), dst, (512 * sect_cnt) / sizeof(uint32_t)); }
 
-// 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3
-void ata_read_identify(int dev, int disable_intr) {
+// 这里所用的drv是逻辑编号 ATA0、ATA1下的Master、Salve的drv分别为0,1,2,3
+void ata_read_identify(int drv, int disable_intr) {
     uint8_t ctlv = 0x00;
     if (disable_intr != 0) {
         ctlv |= ATA_CTL_NIEN;
     }
-    outb(ctlv, REG_CTL(dev));
-    outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev));  // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行
-    outb(ATA_CMD_IDENTIFY, REG_CMD(dev));
+    outb(ctlv, REG_CTL(drv));
+    outb(0x00 | ((drv & 0x01) << 4), REG_DEVICE(drv));  // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行
+    outb(ATA_CMD_IDENTIFY, REG_CMD(drv));
 }
 
 void ata_read_identity_string(const uint16_t *identify, int bgn, int end, char *buf) {
@@ -82,9 +74,17 @@ void ata_read_identity_string(const uint16_t *identify, int bgn, int end, char *
 // 《AT Attachment 8 - ATA/ATAPI Command Set》
 void ide_ata_init() {
     for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
-        int dev = i;
+        int drv_no = i;
         memset(ide_drives + i, 0, sizeof(ide_drive_t));
 
+        ide_drive_t *drv = ide_drives + drv_no;
+
+        INIT_MUTEX(&drv->request_mutex);
+
+        drv->request_queue.count = 0;
+        INIT_LIST_HEAD(&drv->request_queue.list);
+        semaphore_init(&drv->request_queue.sem, 0);
+
         // https://wiki.osdev.org/ATA_PIO_Mode
         // To use the IDENTIFY command, select a target drive by sending 0xA0 for the master drive, or 0xB0 for the
         // slave, to the "drive select" IO port. On the Primary bus, this would be port 0x1F6. Then set the Sectorcount,
@@ -117,9 +117,9 @@ void ide_ata_init() {
         //  2. 等到status的BSY位清除
         //  3. 等到status的DRQ位或ERR位设置
 
-        ata_read_identify(dev, 1);
+        ata_read_identify(drv_no, 1);
 
-        uint8_t status = inb(REG_STATUS(dev));
+        uint8_t status = inb(REG_STATUS(drv_no));
         if (status == 0 || (status & ATA_STATUS_ERR) || (status & ATA_STATUS_RDY == 0)) {
             ide_drives[i].present = 0;
             continue;
@@ -128,7 +128,7 @@ void ide_ata_init() {
         }
 
         printk("ata[%d] status %x %s exists\n", i, status, ide_drives[i].present == 1 ? "" : "not");
-        insl(REG_DATA(dev), identify, SECT_SIZE / sizeof(uint32_t));
+        insl(REG_DATA(drv_no), identify, SECT_SIZE / sizeof(uint32_t));
 
         // 第49个word的第8个bit位表示是否支持DMA
         // 第83个word的第10个bit位表示是否支持LBA48,为1表示支持。
@@ -196,11 +196,12 @@ void ide_ata_init() {
     }
 }
 
+#if 0
 void ata_init() {
     // 初始化hard_disk与中断函数之间的信号量
 
     disk_request_t r;
-    r.dev = 0;
+    r.drv = 0;
     r.buf = (void *)identify;
     r.count = 1;
     r.pos = 0;
@@ -238,9 +239,10 @@ void ata_init() {
         printd("%04x.", p[i]);
     }
 }
+#endif
 
 // ATA_CMD_READ_DMA_EXT
-void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) {
+void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest) {
     // Intel®
     //  82801CA (ICH3), 82801BA
     // (ICH2), 82801AA (ICH), and 82801AB
@@ -259,8 +261,12 @@ 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).
 
+    int channel = (drv >> 1) & 0x01;
+    assert(channel == 0 || channel == 1);
+    ide_pci_controller_t *pci = ide_pci_controller + channel;
+
     // 停止DMA
-    outb(PCI_IDE_CMD_STOP, ide_pci_controller.bus_cmd);
+    outb(PCI_IDE_CMD_STOP, pci->bus_cmd);
 
     // 配置描述符表
     unsigned long dest_paddr = va2pa(dest);
@@ -270,75 +276,78 @@ void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) {
     const uint32_t _64K = 1 << 16;
     assert(((dest_paddr + size) & _64K) == (dest_paddr & _64K));
 
-    ide_pci_controller.prdt[0].phys_addr = dest_paddr;
-    ide_pci_controller.prdt[0].byte_count = size;
-    ide_pci_controller.prdt[0].reserved = 0;
-    ide_pci_controller.prdt[0].eot = 1;
-    outl(va2pa(ide_pci_controller.prdt), ide_pci_controller.bus_prdt);
+    pci->prdt[0].phys_addr = dest_paddr;
+    pci->prdt[0].byte_count = size;
+    pci->prdt[0].reserved = 0;
+    pci->prdt[0].eot = 1;
+    outl(va2pa(pci->prdt), pci->bus_prdt);
 
-    // printk("paddr: %x prdt: %x %x prdte %x %x\n", dest_paddr, ide_pci_controller.prdt,
-    // va2pa(ide_pci_controller.prdt),
-    //        ide_pci_controller.prdt[0].phys_addr, *(((unsigned int *)ide_pci_controller.prdt) + 1));
+    // printk("paddr: %x prdt: %x %x prdte %x %x\n", dest_paddr, pci->prdt,
+    // va2pa(pci->prdt),
+    //        pci->prdt[0].phys_addr, *(((unsigned int *)pci->prdt) + 1));
 
     // 清除中断位和错误位
     // 这里清除的方式是是设置1后清除
-    outb(PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, ide_pci_controller.bus_status);
+    outb(PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, pci->bus_status);
 
     // 不再设置nIEN,DMA需要中断
-    outb(0x00, REG_CTL(dev));
+    outb(0x00, REG_CTL(drv));
 
     // 等待硬盘不BUSY
-    while (inb(REG_STATUS(dev)) & ATA_STATUS_BSY) {
+    while (inb(REG_STATUS(drv)) & ATA_STATUS_BSY) {
         nop();
     }
 
     // 选择DRIVE
-    outb(ATA_LBA48_DEVSEL(dev), REG_DEVICE(dev));
+    outb(ATA_LBA48_DEVSEL(drv), REG_DEVICE(drv));
 
     // 先写扇区数的高字节
-    outb((count >> 8) & 0xFF, REG_NSECTOR(dev));
+    outb((count >> 8) & 0xFF, REG_NSECTOR(drv));
 
     // 接着写LBA48,高三个字节
-    outb((pos >> 24) & 0xFF, REG_LBAL(dev));
-    outb((pos >> 32) & 0xFF, REG_LBAM(dev));
-    outb((pos >> 40) & 0xFF, REG_LBAH(dev));
+    outb((pos >> 24) & 0xFF, REG_LBAL(drv));
+    outb((pos >> 32) & 0xFF, REG_LBAM(drv));
+    outb((pos >> 40) & 0xFF, REG_LBAH(drv));
 
     // 再写扇区数的低字节
-    outb((count >> 0) & 0xFF, REG_NSECTOR(dev));
+    outb((count >> 0) & 0xFF, REG_NSECTOR(drv));
 
     // 接着写LBA48,低三个字节
-    outb((pos >> 0) & 0xFF, REG_LBAL(dev));
-    outb((pos >> 8) & 0xFF, REG_LBAM(dev));
-    outb((pos >> 16) & 0xFF, REG_LBAH(dev));
+    outb((pos >> 0) & 0xFF, REG_LBAL(drv));
+    outb((pos >> 8) & 0xFF, REG_LBAM(drv));
+    outb((pos >> 16) & 0xFF, REG_LBAH(drv));
 
     // 等待硬盘READY
-    while (inb(REG_STATUS(dev)) & ATA_STATUS_RDY == 0) {
+    while (inb(REG_STATUS(drv)) & ATA_STATUS_RDY == 0) {
         nop();
     }
 
-    outb(ATA_CMD_READ_DMA_EXT, REG_CMD(dev));
+    outb(ATA_CMD_READ_DMA_EXT, REG_CMD(drv));
 
     // 这一句非常重要,如果不加这一句
     // 在qemu中用DMA的方式读数据就会读不到数据,而只触是发中断,然后寄存器(Bus Master IDE Status
     // Register)的值会一直是5 也就是INTERRUPT和和ACTIVE位是1,正常应该是4,也就是只有INTERRUPT位为1
     // 在bochs中则加不加这一句不会有影响,都能正常读到数据
-    unsigned int v = pci_read_config_word(pci_cmd(ide_pci_controller.pci, PCI_COMMAND));
+    unsigned int v = pci_read_config_word(pci_cmd(pci->pci, PCI_COMMAND));
     // printk(" ide pci command %04x\n", v);
-    pci_write_config_word(v | PCI_COMMAND_MASTER, pci_cmd(ide_pci_controller.pci, PCI_COMMAND));
+    pci_write_config_word(v | PCI_COMMAND_MASTER, pci_cmd(pci->pci, PCI_COMMAND));
+    // pci_write_config_word(v, pci_cmd(pci->pci, PCI_COMMAND));
 
     // 指定DMA操作为读取硬盘操作,内核用DMA读取,对硬盘而言是写出
     // 并设置DMA的开始位,开始DMA
-    outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, ide_pci_controller.bus_cmd);
+    outb(PCI_IDE_CMD_WRITE | PCI_IDE_CMD_START, pci->bus_cmd);
 }
 
 // TODO
-int ata_dma_stop() {
-    uint8_t x = inb(ide_pci_controller.bus_cmd);
+int ata_dma_stop(int channel) {
+    ide_pci_controller_t *pci = ide_pci_controller + channel;
+
+    uint8_t x = inb(pci->bus_cmd);
     x &= ~PCI_IDE_CMD_START;
-    outb(x, ide_pci_controller.bus_cmd);
+    outb(x, pci->bus_cmd);
 
-    uint8_t status = inb(ide_pci_controller.bus_status);
-    outb(status | PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, ide_pci_controller.bus_status);
+    uint8_t status = inb(pci->bus_status);
+    outb(status | PCI_IDE_STATUS_INTR | PCI_IDE_STATUS_ERR, pci->bus_status);
 
     // TODO
     if (status & PCI_IDE_STATUS_ERR) {
@@ -349,44 +358,44 @@ int ata_dma_stop() {
 }
 
 // ATA_CMD_READ_PIO_EXT
-int ata_pio_read_ext(int dev, uint64_t pos, uint16_t count, int timeout, void *dest) {
+int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count, int timeout, void *dest) {
     // PIO读,禁用中断
-    outb(ATA_CTL_NIEN, REG_CTL(dev));
+    outb(ATA_CTL_NIEN, REG_CTL(drv));
 
     // 等待硬盘不BUSY
-    while (inb(REG_STATUS(dev)) & ATA_STATUS_BSY) {
+    while (inb(REG_STATUS(drv)) & ATA_STATUS_BSY) {
         nop();
     }
 
     // 选择DRIVE
-    outb(ATA_LBA48_DEVSEL(dev), REG_DEVICE(dev));
+    outb(ATA_LBA48_DEVSEL(drv), REG_DEVICE(drv));
 
     // 先写扇区数的高字节
-    outb((count >> 8) & 0xFF, REG_NSECTOR(dev));
+    outb((count >> 8) & 0xFF, REG_NSECTOR(drv));
 
     // 接着写LBA48,高三个字节q
-    outb((pos >> 24) & 0xFF, REG_LBAL(dev));
-    outb((pos >> 32) & 0xFF, REG_LBAM(dev));
-    outb((pos >> 40) & 0xFF, REG_LBAH(dev));
+    outb((pos >> 24) & 0xFF, REG_LBAL(drv));
+    outb((pos >> 32) & 0xFF, REG_LBAM(drv));
+    outb((pos >> 40) & 0xFF, REG_LBAH(drv));
 
     // 再写扇区数的低字节
-    outb((count >> 0) & 0xFF, REG_NSECTOR(dev));
+    outb((count >> 0) & 0xFF, REG_NSECTOR(drv));
 
     // 接着写LBA48,低三个字节
-    outb((pos >> 0) & 0xFF, REG_LBAL(dev));
-    outb((pos >> 8) & 0xFF, REG_LBAM(dev));
-    outb((pos >> 16) & 0xFF, REG_LBAH(dev));
+    outb((pos >> 0) & 0xFF, REG_LBAL(drv));
+    outb((pos >> 8) & 0xFF, REG_LBAM(drv));
+    outb((pos >> 16) & 0xFF, REG_LBAH(drv));
 
-    while (inb(REG_STATUS(dev)) & ATA_STATUS_RDY == 0) {
+    while (inb(REG_STATUS(drv)) & ATA_STATUS_RDY == 0) {
         nop();
     }
 
-    outb(ATA_CMD_READ_PIO_EXT, REG_CMD(dev));
+    outb(ATA_CMD_READ_PIO_EXT, REG_CMD(drv));
 
     while (timeout > 0) {
         timeout--;
 
-        u8 status = inb(REG_STATUS(dev));
+        u8 status = inb(REG_STATUS(drv));
         if ((status & ATA_STATUS_BSY) == 0 && (status & ATA_STATUS_DRQ) != 0) {
             break;
         }
@@ -399,22 +408,16 @@ int ata_pio_read_ext(int dev, uint64_t pos, uint16_t count, int timeout, void *d
         return -1;
     }
 
-    insl(REG_DATA(dev), dest, (SECT_SIZE * count) / sizeof(uint32_t));
+    insl(REG_DATA(drv), dest, (SECT_SIZE * count) / sizeof(uint32_t));
 
     return 0;
 }
 
-uint8_t ata_pci_bus_status() {
-    uint8_t st = 0;
-    st = inb(ide_pci_controller.bus_status);
-
-    outb(PCI_IDE_STATUS_INTR, ide_pci_controller.bus_status);
-
-    return st;
-}
+// uint8_t ata_pci_bus_status() {
+//     uint8_t st = 0;
+//     st = inb(ide_pci_controller.bus_status);
 
-unsigned int ATA_CHL0_CMD_BASE = 0x1F0;
-unsigned int ATA_CHL1_CMD_BASE = 0x170;
+//     outb(PCI_IDE_STATUS_INTR, ide_pci_controller.bus_status);
 
-unsigned int ATA_CHL0_CTL_BASE = 0x3F6;
-unsigned int ATA_CHL1_CTL_BASE = 0x376;
+//     return st;
+// }
index e0f71d170f3d65f7f9d35f2777068d292af87ae6..e62aee3f751e02142dbb2c04fb397bf6704c9f22 100644 (file)
@@ -9,8 +9,8 @@
 
 #pragma once
 
-extern unsigned int ATA_CHL0_CMD_BASE;
-extern unsigned int ATA_CHL1_CMD_BASE;
+extern unsigned int IDE_CHL0_CMD_BASE;
+extern unsigned int IDE_CHL1_CMD_BASE;
 
 // CTL其实不用BASE,只有一个寄存器
 // 这么写纯粹是为了代码好看
@@ -20,8 +20,8 @@ extern unsigned int ATA_CHL1_CMD_BASE;
 // bit2: SRST   Software Reset
 // bit1: IEN    disable Interrupt
 // bit0: 0
-extern unsigned int ATA_CHL0_CTL_BASE;
-extern unsigned int ATA_CHL1_CTL_BASE;
+extern unsigned int IDE_CHL0_CTL_BASE;
+extern unsigned int IDE_CHL1_CTL_BASE;
 
 #define ATA_DATA 0
 
@@ -47,7 +47,7 @@ extern unsigned int ATA_CHL1_CTL_BASE;
 // bit5: Obsolete
 // bit4: DRIVE
 // bit[0, 3] HS 如果L为0就是磁头号Head Number,如果L为1,则为LBA的24-27位
-#define ATA_LBA48_DEVSEL(dev) (0x40 | ((dev & 0x01) << 4))
+#define ATA_LBA48_DEVSEL(drv) (0x40 | ((drv & 0x01) << 4))
 #define ATA_DEVICE 6
 
 #define ATA_CMD 7
@@ -95,24 +95,24 @@ extern unsigned int ATA_CHL1_CTL_BASE;
 #define ATA_CTL_SRST 0x04       /* soft reset controller */
 #define ATA_CTL_NIEN 0x02       /* disable interrupts */
 
-#define ATA_GET_CHL(dev) (((dev) >> 1) & 0x01)
-#define ATA_GET_DEV(dev) (((dev) >> 1) & 0x01)
+#define ATA_GET_CHL(drv) (((drv) >> 1) & 0x01)
+#define ATA_GET_DEV(drv) (((drv) >> 1) & 0x01)
 
-#define REG_CMD_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CMD_BASE + offset) : (ATA_CHL0_CMD_BASE + offset))
-#define REG_CTL_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CTL_BASE + offset) : (ATA_CHL0_CTL_BASE + offset))
+#define REG_CMD_BASE(drv, offset) (ATA_GET_CHL(drv) ? (IDE_CHL1_CMD_BASE + offset) : (IDE_CHL0_CMD_BASE + offset))
+#define REG_CTL_BASE(drv, offset) (ATA_GET_CHL(drv) ? (IDE_CHL1_CTL_BASE + offset) : (IDE_CHL0_CTL_BASE + offset))
 
-#define REG_DATA(dev) REG_CMD_BASE(dev, ATA_DATA)
-#define REG_ERR(dev) REG_CMD_BASE(dev, ATA_ERR)
-#define REG_NSECTOR(dev) REG_CMD_BASE(dev, ATA_NSECTOR)
-#define REG_LBAL(dev) REG_CMD_BASE(dev, ATA_LBAL)
-#define REG_LBAM(dev) REG_CMD_BASE(dev, ATA_LBAM)
-#define REG_LBAH(dev) REG_CMD_BASE(dev, ATA_LBAH)
-#define REG_DEVICE(dev) REG_CMD_BASE(dev, ATA_DEVICE)
-#define REG_STATUS(dev) REG_CMD_BASE(dev, ATA_STATUS)
-#define REG_FEATURES(dev) REG_CMD_BASE(dev, ATA_FEATURES)
+#define REG_DATA(drv) REG_CMD_BASE(drv, ATA_DATA)
+#define REG_ERR(drv) REG_CMD_BASE(drv, ATA_ERR)
+#define REG_NSECTOR(drv) REG_CMD_BASE(drv, ATA_NSECTOR)
+#define REG_LBAL(drv) REG_CMD_BASE(drv, ATA_LBAL)
+#define REG_LBAM(drv) REG_CMD_BASE(drv, ATA_LBAM)
+#define REG_LBAH(drv) REG_CMD_BASE(drv, ATA_LBAH)
+#define REG_DEVICE(drv) REG_CMD_BASE(drv, ATA_DEVICE)
+#define REG_STATUS(drv) REG_CMD_BASE(drv, ATA_STATUS)
+#define REG_FEATURES(drv) REG_CMD_BASE(drv, ATA_FEATURES)
 
-#define REG_CMD(dev) REG_CMD_BASE(dev, ATA_CMD)
-#define REG_CTL(dev) REG_CTL_BASE(dev, ATA_CTL)
+#define REG_CMD(drv) REG_CMD_BASE(drv, ATA_CMD)
+#define REG_CTL(drv) REG_CTL_BASE(drv, ATA_CTL)
 
 #define ATA_IDENT_DEVTYPE 0
 #define ATA_IDENT_CYLINDERS 2
index 6b97d0dfa04d30d61e55c11cd755f07733decbc2..837eb00625948f1162ef178cf7821320647ce663 100644 (file)
 #include <task.h>
 #include <wait.h>
 
-ide_pci_controller_t ide_pci_controller;
+ide_pci_controller_t ide_pci_controller[NR_IDE_CONTROLLER];
 
-extern unsigned int ATA_CHL0_CMD_BASE;
-extern unsigned int ATA_CHL1_CMD_BASE;
+unsigned int IDE_CHL0_CMD_BASE = 0x1F0;
+unsigned int IDE_CHL1_CMD_BASE = 0x170;
 
-extern unsigned int ATA_CHL0_CTL_BASE;
-extern unsigned int ATA_CHL1_CTL_BASE;
+unsigned int IDE_CHL0_CTL_BASE = 0x3F6;
+unsigned int IDE_CHL1_CTL_BASE = 0x376;
 
+// 《PCI IDE Controller Specification》
+// 《Programming Interface for Bus Master IDE Controller》
 void ide_pci_init(pci_device_t *pci) {
     unsigned int v;
 
@@ -28,37 +30,38 @@ void ide_pci_init(pci_device_t *pci) {
     // printk(" ide pci command %04x\n", v);
 
     v = pci_read_config_byte(pci_cmd(pci, PCI_PROGIF));
-    printk(" ide pci program interface %02x\n", v);
+    printd("ide pci program interface %02x\n", v);
 
     unsigned int iobase = pci_read_config_long(pci_cmd(pci, PCI_BAR4));
-    printk(" ide pci Base IO Address Register %08x\n", iobase);
-    iobase &= 0xFFFC;  // 最低为0是内存地址为1是端口地址
-    ide_pci_controller.bus_iobase = iobase;
-    ide_pci_controller.bus_cmd = iobase + PCI_IDE_CMD;
-    ide_pci_controller.bus_status = iobase + PCI_IDE_STATUS;
-    ide_pci_controller.bus_prdt = iobase + PCI_IDE_PRDT;
-    ide_pci_controller.prdt = (prdte_t *)alloc_one_page(0);
-
-    int i;
-    printk(" BARS: ");
-    for (i = 0; i < BARS_CNT; ++i) {
-        printk("%08x ", pci->bars[i]);
-        pci->bars[i] &= (~1UL);
-    }
-    printk("\n");
 
-    ATA_CHL0_CMD_BASE = pci->bars[0] ? pci->bars[0] : ATA_CHL0_CMD_BASE;
-    ATA_CHL0_CTL_BASE = pci->bars[1] ? pci->bars[1] : ATA_CHL0_CTL_BASE;
+    for (int i = 0; i < NR_IDE_CONTROLLER; i++) {
+        iobase += i * 8;  // secondary channel 需要加8
+        printd("ide pci Base IO Address Register %08x\n", iobase);
+        iobase &= 0xFFFC;  // 最低为0是内存地址为1是端口地址
+        ide_pci_controller[i].bus_iobase = iobase;
+        ide_pci_controller[i].bus_cmd = iobase + PCI_IDE_CMD;
+        ide_pci_controller[i].bus_status = iobase + PCI_IDE_STATUS;
+        ide_pci_controller[i].bus_prdt = iobase + PCI_IDE_PRDT;
+        ide_pci_controller[i].prdt = (prdte_t *)alloc_one_page(0);
+
+        printd("BARS: ");
+        for (int j = 0; j < BARS_CNT; ++j) {
+            printd("%08x ", pci->bars[j]);
+            pci->bars[j] &= (~1UL);
+        }
+        printd("\n");
+
+        ide_pci_controller[i].pci = pci;
+    }
 
-    ATA_CHL1_CMD_BASE = pci->bars[2] ? pci->bars[2] : ATA_CHL1_CMD_BASE;
-    ATA_CHL1_CTL_BASE = pci->bars[3] ? pci->bars[3] : ATA_CHL1_CTL_BASE;
+    IDE_CHL0_CMD_BASE = pci->bars[0] ? pci->bars[0] : IDE_CHL0_CMD_BASE;
+    IDE_CHL0_CTL_BASE = pci->bars[1] ? pci->bars[1] : IDE_CHL0_CTL_BASE;
 
-    ide_pci_controller.pci = pci;
+    IDE_CHL1_CMD_BASE = pci->bars[2] ? pci->bars[2] : IDE_CHL1_CMD_BASE;
+    IDE_CHL1_CTL_BASE = pci->bars[3] ? pci->bars[3] : IDE_CHL1_CTL_BASE;
 
-    printd("channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x\n", ATA_CHL0_CMD_BASE, ATA_CHL0_CTL_BASE,
-           ATA_CHL1_CMD_BASE, ATA_CHL1_CTL_BASE);
-    // printl(18, "channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x", HD_CHL0_CMD_BASE, HD_CHL0_CTL_BASE,
-    // HD_CHL1_CMD_BASE, HD_CHL1_CTL_BASE);
+    printd("ide channel 0: cmd %04x ctl %04x\n", IDE_CHL0_CMD_BASE, IDE_CHL0_CTL_BASE);
+    printd("ide channel 1: cmd %04x ctl %04x\n", IDE_CHL1_CMD_BASE, IDE_CHL1_CTL_BASE);
 }
 
 // void ide_status() {
@@ -82,6 +85,11 @@ void ide_pci_init(pci_device_t *pci) {
 const char *pci_get_info(unsigned int classcode, unsigned int progif);
 void init_pci_controller(unsigned int classcode) {
     pci_device_t *pci = pci_find_device_by_classcode(classcode);
+    if (pci == NULL) {
+        printk("can not find pci classcode: %08x", classcode);
+        panic("can not find ide controller");
+    }
+    assert(pci->intr_line < 16);
     if (pci != 0 && pci->intr_line < 16) {
         printk("found pci %03d:%02d.%d #%02d %04X:%04X ProgIF %02x %s\n", pci->bus, pci->dev, pci->devfn,
                pci->intr_line, pci->vendor, pci->device, pci->progif, pci_get_info(pci->classcode, pci->progif));
@@ -98,7 +106,6 @@ void init_pci_controller(unsigned int classcode) {
 extern semaphore_t disk_intr_sem;
 
 extern void *mbr_buf;
-extern ide_pci_controller_t ide_pci_controller;
 extern uint32_t disk_request_cnt;
 extern uint32_t disk_handled_cnt;
 
@@ -106,12 +113,15 @@ uint8_t ata_pci_bus_status();
 
 volatile uint32_t disk_inter_cnt = 0;
 
-void ide_irq_bh_handler() {
+void ata_dma_stop(int channel);
+void ide_irq_bh_handler(void *arg) {
     disk_inter_cnt++;
 
+    int channel = (int)arg;
+
     // printl(MPL_IDE, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
     printlxy(MPL_IDE, MPO_IDE, "disk irq %u req %u consumed %u ", disk_inter_cnt, disk_request_cnt, disk_handled_cnt);
-    ata_dma_stop();
+
     // up里不会立即重新调度进程
     up(&disk_intr_sem);
 }
@@ -119,18 +129,27 @@ void ide_irq_bh_handler() {
 void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) {
     // printk("ide irq %d handler pci status: 0x%02x\n", irq, ata_pci_bus_status());
 
-    add_irq_bh_handler(ide_irq_bh_handler);
+    int channel = irq == 14 ? 0 : 1;
+    ata_dma_stop(channel);
+
+    add_irq_bh_handler(ide_irq_bh_handler, &channel);
 }
 
+void ide1_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) { panic("ide 0"); }
+
+void ide_ata_init();
 void ide_init() {
-    // memset((void *)&drv, 0, sizeof(drv));
-    memset(&ide_pci_controller, 0, sizeof(ide_pci_controller));
+    memset(ide_pci_controller, 0, sizeof(ide_pci_controller[0]) * NR_IDE_CONTROLLER);
+
+    // 读PCI里 IDE相关寄存器的配置
+    // init_pci_controller(0x0106);
+    init_pci_controller(0x0101);
+    // init_pci_controller(0x7010);
 
-    void ide_ata_init();
+    // 读IDE 硬盘的identity
     ide_ata_init();
 
     request_irq(0x0E, ide_irq_handler, "hard", "IDE");
 
-    // init_pci_controller(0x0106);
-    init_pci_controller(0x0101);
+    request_irq(0x0F, ide_irq_handler, "hard", "IDE");
 }
index 46df6c09ed413267406e6fe47f18a1e8e106a321..1a63a920c2b7268aa1a2b38e8e1c570c7eff0c3c 100644 (file)
@@ -9,7 +9,9 @@
 
 #pragma once
 
+#include <disk.h>
 #include <pci.h>
+#include <semaphore.h>
 #include <system.h>
 #include <task.h>
 
@@ -181,5 +183,21 @@ typedef struct _ide_pci_controller {
     int done;
 } ide_pci_controller_t;
 
+#define NR_IDE_CONTROLLER 2
+
+typedef struct _ide_drive {
+    int present;
+    int dma;
+    uint64_t lba48;
+    uint64_t max_lba;
+
+    semaphore_t request_mutex;
+
+    disk_request_queue_t request_queue;
+} ide_drive_t;
+
+#define MAX_IDE_DRIVE_CNT 4
+extern ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT];
+
 void sleep_on_ide();
-void wait_on_ide();
\ No newline at end of file
+void wait_on_ide();
index e1f729a794d9c9f5226917020f1c0fec95877913..e26b6f58502e329240f76116bdfd11361c9181e6 100644 (file)
@@ -54,7 +54,7 @@ char kbd_char_tbl[] = {
 
 // TODO 改造成环形缓冲区
 uint8_t scan_code;
-void kbd_bh_handler() {
+void kbd_bh_handler(void *arg) {
     kbd_debug(scan_code);
     if (0x80 & scan_code) {  // break code
         return;
@@ -66,7 +66,7 @@ void kbd_bh_handler() {
 
 void kbd_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
     scan_code = inb(0x60);
-    add_irq_bh_handler(kbd_bh_handler);
+    add_irq_bh_handler(kbd_bh_handler, NULL);
 }
 
 extern tty_t *const default_tty;
index 4c35d0a101ce47d409182e40829d34a08c42d43a..21718d1d381711571815494dcfa955a66bea2b4b 100644 (file)
@@ -153,7 +153,7 @@ void dump_pci_dev() {
         //        pci->progif, pci->bus, pci->intr_line);
         // printk("%s\n", pci_get_info(pci->classcode, pci->progif));
         printk("PCI %03d:%02d.%d #%02d %04X:%04X %s\n", pci->bus, pci->dev, pci->devfn, pci->intr_line, pci->vendor,
-               pci->device, pci_get_info(pci->classcode, pci->progif));
+               pci->classcode, pci_get_info(pci->classcode, pci->progif));
 #if 0
         switch (pci->hdr_type) {
         case PCI_HDRTYPE_NORMAL:
@@ -228,6 +228,9 @@ void setup_pci() {
     }
 
     dump_pci_dev();
+
+    // while (1)
+    //     ;
 }
 
 typedef struct pci_info {
index 6e5608013e085c2a4859998d9d52e87eb45aaa76..d5423493e745f642c0255c1fdaceeb1371bd7a49 100644 (file)
@@ -20,7 +20,7 @@ typedef enum {
 } disk_request_cmd_t;
 
 typedef struct disk_request {
-    int dev;
+    dev_t dev;
     uint64_t pos;                // 扇区号
     uint16_t count;              // 扇区数
     void *buf;                   // 到的缓冲区
@@ -43,4 +43,4 @@ typedef struct {
     list_head_t list;
 } disk_request_queue_t;
 
-void send_disk_request(disk_request_t *r);
\ No newline at end of file
+void send_disk_request(disk_request_t *r);
index c96eae49966d869bea5651f27c49e725f8688eba..bec6002b828f1989569c514e7bba62d515541660 100644 (file)
@@ -46,6 +46,7 @@ typedef struct irq_desc {
 
 typedef struct irq_bh_action {
     void (*handler)();
+    void *arg;
     struct irq_bh_action *next;
 } irq_bh_action_t;
 
@@ -56,7 +57,7 @@ int request_irq(unsigned int irq,
                 // void (*handler)(pt_regs_t *, unsigned int),
                 void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
 
-void add_irq_bh_handler(void (*handler)());
+void add_irq_bh_handler(void (*handler)(), void *arg);
 
 int open_irq(unsigned int irq);
 int close_irq(unsigned int irq);
index 72f6a52807f9075720a9aaa95e8f2e0a07477cf8..70d86ec7fec9ac46faa455a144d8cf2cf2340b6a 100644 (file)
@@ -33,5 +33,11 @@ void down(semaphore_t *s);
 void up(semaphore_t *s);
 
 #define DECLARE_MUTEX(name) semaphore_t name = SEMAPHORE_INITIALIZER(name, 1)
+
+#define INIT_MUTEX(ptr)                      \
+    do {                                     \
+        (ptr)->cnt = 1;                      \
+        INIT_LIST_HEAD(&((ptr)->wait_list)); \
+    } while (0)
 void mutex_lock(semaphore_t *);
 void mutex_unlock(semaphore_t *);
index d353804e7af355927b351456e2bb80b6897273ed..9189c401654a340305a3161062e8074f9917dba7 100644 (file)
@@ -139,7 +139,7 @@ typedef struct pt_regs {
     u16 ss, _ss;
 } __attribute__((packed)) pt_regs_t;
 
-typedef unsigned long dev_t;
+typedef uint32_t dev_t;
 
 typedef struct system {
     u32 mmap_addr;
index 3921de5d1c6d177392b7f885c931dab20d63f2cf..438386a5e876a557e4eb8407710d4db763c5cb7e 100644 (file)
@@ -23,7 +23,8 @@ unsigned int sys_clock() { return jiffies; }
 void debug_print_all_tasks();
 
 void dump_irq_nr_stack();
-void clk_bh_handler();
+void clk_bh_handler(void *arg);
+
 void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
     // if (jiffies % 100 == 0) {
     // printl(MPL_CLOCK, "clock irq: %d", jiffies);
@@ -45,13 +46,13 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
 
     assert(current->ticks <= TASK_MAX_PRIORITY);  // 防止ticks被减到0后再减溢出
 
-    add_irq_bh_handler(clk_bh_handler);
+    add_irq_bh_handler(clk_bh_handler, NULL);
 }
 
 // 开中断执行这个函数
 // 后续放到一个内核任务中去做,需要先把禁止内核抢占做了
 const char *task_state(unsigned int state);
-void clk_bh_handler() {
+void clk_bh_handler(void *arg) {
     task_union *p = 0;
     list_head_t *t = 0;
     list_head_t *pos = 0;
@@ -60,7 +61,7 @@ void clk_bh_handler() {
         // printk("%s state: %s\n", p->name, task_state(p->state));
         assert(p->state == TASK_WAIT);
         assert(p->delay_jiffies != 0);
-        if (jiffies > p->delay_jiffies) {
+        if (p->delay_jiffies > 0 && jiffies > p->delay_jiffies) {
             list_del(&p->pend);
             p->delay_jiffies = 0;
             p->state = TASK_READY;
index 4517a85658979348c0297b48eada5ab1f26bdbae..b8286940e213640a6b097438f35021e367e84760 100644 (file)
@@ -162,7 +162,7 @@ void irq_bh_handler() {
         }
 
         while (action != NULL) {
-            action->handler();
+            action->handler(action->arg);
             irq_bh_action_t *p = action;
             action = action->next;
             kfree(p);
@@ -218,7 +218,7 @@ int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, voi
     return 0;
 }
 
-void add_irq_bh_handler(void (*handler)()) {
+void add_irq_bh_handler(void (*handler)(), void *arg) {
     // 只能在中断处理函数中调用
     assert(irq_disabled());
 
@@ -227,12 +227,12 @@ void add_irq_bh_handler(void (*handler)()) {
     assert(p != NULL);
 
     p->handler = handler;
+    p->arg = arg;
 
     if (irq_bh_actions_end == NULL) {
         assert(irq_bh_actions == NULL);
         irq_bh_actions = p;
         irq_bh_actions_end = p;
-
     } else {
         assert(irq_bh_actions != NULL);
         irq_bh_actions_end->next = p;
index 54fab03dac33e9f839abb4591f02a5ad0f9222ff..b710ee379b96894913f49b9d5a4a3f4d112f6e6e 100644 (file)
@@ -166,10 +166,10 @@ const char *task_state(unsigned int state) {
 void debug_print_all_tasks() {
     task_union *p = 0;
     list_head_t *pos = 0, *t = 0;
-    printl(MPL_TASK_TITLE, "         NAME     STATE TK/PI TURN       SCHED      KEEP");
+    printl(MPL_TASK_TITLE, "         NAME       STATE TK/PI TURN       SCHED      KEEP");
     list_for_each_safe(pos, t, &all_tasks) {
         p = list_entry(pos, task_union, list);
-        printl(MPL_TASK_0 + p->pid, "%08x%s%4s:%u %s %02u/%02u %-10u %-10u %-10u", p,
+        printl(MPL_TASK_0 + p->pid, "%08x%s%-6s:%u %s %02u/%02u %-10u %-10u %-10u", p,
                p->state == TASK_RUNNING ? ">" : " ", p->name, p->pid, task_state(p->state), p->ticks, p->priority,
                p->turn, p->sched_cnt, p->sched_keep_cnt);
     }
@@ -245,6 +245,7 @@ void schedule() {
     }
 
     assert(current->state == TASK_RUNNING);
+
     irq_restore(iflags);
 }
 
index a410fe3b39d171b33c21eaeb77dc06d0762ae1ad..8b2aa57c99216511bae9704fb167a9f4449414b9 100644 (file)
@@ -80,7 +80,7 @@ void setup_kernel() {
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
     extern tty_t *const monitor_tty;
-    // tty_switch(monitor_tty);
+    tty_switch(monitor_tty);
 
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
@@ -90,11 +90,3 @@ void setup_kernel() {
     void ide_init();
     ide_init();
 }
-
-// 在开中断的情况下继续初始化的内容
-void setup_under_irq() {
-    void ata_init();
-    ata_init();
-    return;
-    setup_fs();
-}
index 6f204cf6593ba1a268e6d0cee3c9c5eac266cb41..15906f0f1a1f0c9c3263b4938375a6fa4e80e592 100644 (file)
@@ -95,10 +95,13 @@ ret_from_fork_krnl:
     popfl               // EFLAGS
     addl    $8, %esp    // ESP SS
 
+    pushl   %ecx
     call    *%edx
 
     addl    $4, %esp    // CALL PUSH EIP
 
+    addl    $4, %esp    // ecx: arg
+
     // TODO
     // add exit here
 
index 124d6f2d06e4c612d4b1593b8cd5e9823d80d00d..1717762fe849213bbc9a1cfd3befe1b2cb7ffc5b 100644 (file)
@@ -134,7 +134,7 @@ void setup_irqs() {
     request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
     // request_irq(0x0E, default_ide_irq_handler, "hard", "IDE");
     for (int i = 0; i < 16; i++) {
-        if (i != 0 && i != 1 && i != 10 && i != 14) {
+        if (i != 0 && i != 1 && i != 10 && i != 14 && i != 15) {
             request_irq(i, default_irq_handler, "default", "default");
         }
     }
@@ -152,6 +152,7 @@ void setup_irqs() {
     open_irq(IRQ_CLOCK);
     open_irq(IRQ_KEYBOARD);
     open_irq(IRQ_DISK);
+    open_irq(15);
 }
 
 void boot_irq_handler();
index 8bc22f58daa96bfec9d0a501f31cba9858f5d5c5..741a933c094639beb26bffccae83a7eba89dccc5 100644 (file)
@@ -9,32 +9,36 @@
 
 #include <completion.h>
 #include <disk.h>
+#include <ide.h>
 #include <sched.h>
 
-disk_request_queue_t disk_request_queue;
-
 // task disk与中断函数之间的信号量
 semaphore_t disk_intr_sem;
 
-DECLARE_MUTEX(disk_request_mutex);
-
-void disk_init() {
-    disk_request_queue.count = 0;
-    INIT_LIST_HEAD(&disk_request_queue.list);
-    // disk_request_queue.sem.cnt = 0;
-    // INIT_LIST_HEAD(&disk_request_queue.sem.wait_list);
-    semaphore_init(&disk_request_queue.sem, 0);
+// task disk 之间发送命令的互斥量
+DECLARE_MUTEX(disk_cmd_mutex);
 
-    semaphore_init(&disk_intr_sem, 0);
-}
+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");
     }
 
+    // TODO: 转换
+    int drv_no = r->dev;
+    // assert(drv_no == 0);
+
+    assert(drv_no >= 0);
+    assert(drv_no <= MAX_IDE_DRIVE_CNT);
+
+    ide_drive_t *drv = ide_drives + drv_no;
+
+    assert(drv->present == 1);
+
     // 这个用来让task_disk唤醒自己
     semaphore_init(&r->sem, 0);
 
@@ -47,47 +51,66 @@ void send_disk_request(disk_request_t *r) {
         panic("disk DMA read cross 64K");
     }
 
-    mutex_lock(&disk_request_mutex);
+    mutex_lock(&drv->request_mutex);
     disk_request_cnt++;
-    list_add_tail(&r->list, &disk_request_queue.list);
-    mutex_unlock(&disk_request_mutex);
+    list_add_tail(&r->list, &drv->request_queue.list);
+    mutex_unlock(&drv->request_mutex);
 
     // 唤醒task_disk
-    up(&disk_request_queue.sem);
+    up(&drv->request_queue.sem);
 
     // 等待被task_disk唤醒
     down(&r->sem);
 }
 
-void disk_task_entry() {
+void disk_task_entry(int arg) {
     int r_cnt = 0;
     while (1) {
-        // printk("wait for new hard disk request\n");
-        down(&disk_request_queue.sem);
-        // printk("hard disk request: %d\n", disk_request_queue.count++);
+        // 如果要改造成每个drive对应一个内核任务的话
+        // 就要注意共享disk_intr_sem的问题
+        // 目前只支持drv_no == 0
+        int drv_no = arg;
+        ide_drive_t *drv = ide_drives + drv_no;
+        if (drv->present == 0) {
+            panic("disk not present");
+        }
+
+        // 为了在DEBUG时看到RUNNING
+        for (int i = 0; i < 3; i++) {
+            asm("hlt;");
+        }
+
+        // printk("wait request for hard disk %d\n", drv_no);
+        down(&drv->request_queue.sem);
+        // printk("hard disk %d\n", drv_no);
 
-        mutex_lock(&disk_request_mutex);
+        mutex_lock(&drv->request_mutex);
         disk_request_t *r;
-        r = list_first_entry(&disk_request_queue.list, disk_request_t, list);
+        r = list_first_entry(&drv->request_queue.list, disk_request_t, list);
         if (NULL == r) {
             panic("no disk request");
         }
 
         list_del(&r->list);
         disk_handled_cnt++;
-        mutex_unlock(&disk_request_mutex);
+        mutex_unlock(&drv->request_mutex);
 
+        // 目前这个disk_cmd_mutex是用于两个通道四个DRIVE之间互斥
+        // 目前还不确定两个通道之间能否同时执行
+        // 后续要把disk分成两个进程,分别负责channel 0 1
+        // 这里再视情况改写
+        mutex_lock(&disk_cmd_mutex);
         switch (r->command) {
         case DISK_REQ_IDENTIFY:
             assert(r->count == 1);
-            void ata_read_identify(int dev, int disable_intr);
-            ata_read_identify(r->dev, 0);
+            void ata_read_identify(int drv, int disable_intr);
+            ata_read_identify(drv_no, 0);
             break;
         case DISK_REQ_READ:
             assert(r->count > 0);
             assert(r->buf != NULL);
-            void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest);
-            ata_dma_read_ext(r->dev, r->pos, r->count, r->buf);
+            void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest);
+            ata_dma_read_ext(drv_no, r->pos, r->count, r->buf);
             break;
         default:
             break;
@@ -95,11 +118,11 @@ void disk_task_entry() {
 
         // 等待硬盘中断
         down(&disk_intr_sem);
-
+        mutex_unlock(&disk_cmd_mutex);
         // 读数据
         if (DISK_REQ_IDENTIFY == r->command) {
-            void ata_read_data(int dev, int sect_cnt, void *dst);
-            ata_read_data(r->dev, 1, r->buf);
+            void ata_read_data(int drv_no, int sect_cnt, void *dst);
+            ata_read_data(drv_no, 1, r->buf);
         }
 
         // 唤醒等待该请求的进程
index 7c7383da9353d7eb7ae5852b27bb3dfc5d5944ce..2e541ad14d22b90d14efc38826114c8e33905a71 100644 (file)
@@ -13,11 +13,6 @@ int sysc_wait(uint32_t ticks);
 void init_task_entry() {
     current->priority = 10;
 
-    // 继续内核未完成的初始化
-    // 这些初始化在开中断的情况下完成
-    void setup_under_irq();
-    setup_under_irq();
-
     while (1) {
         asm("sti;hlt;");
         sysc_wait(2);
index 5c0c700e96735676a8af6a97324cd15779188d58..cece7406b890f5401e2ca757185367ac4be153e9 100644 (file)
@@ -25,7 +25,7 @@ int sysc_wait(uint32_t ticks);
 
 #define get_eflags(x) __asm__ __volatile__("pushfl; popl %0;" : "=g"(x)::"memory")
 
-void kernel_task(char *name, void *entry) {
+void kernel_task(char *name, void *entry, void *arg) {
     pt_regs_t regs;
 
     memset((void *)&regs, 0, sizeof(regs));
@@ -33,6 +33,9 @@ void kernel_task(char *name, void *entry) {
     // 内核任务入口
     regs.edx = (unsigned long)entry;
 
+    // 参数
+    regs.ecx = (unsigned long)arg;
+
     regs.eax = (u32)name;
 
     // 创建内核任务的时候就直接指定其在fork后走的路径
@@ -103,6 +106,7 @@ void taskA_entry() {
         memset(disk_buf1, 0, 512);
 
         disk_request_t r;
+        r.dev = 0;
         r.command = DISK_REQ_READ;
         r.pos = sect_nr;
         r.count = 1;
@@ -126,12 +130,13 @@ void taskB_entry() {
         uint64_t sect_nr = get_next_deubug_sect_nr();
         memset(disk_buf2, 0, 512);
         disk_request_t r;
+        r.dev = 2;
         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);
+        // verify_hd_data(sect_nr, disk_buf2, current->name);
 
         for (int i = 0; i < 1; i++) {
             asm("hlt;");
@@ -165,17 +170,18 @@ void root_task_entry() {
     void disk_init();
     disk_init();
 
-    kernel_task("init", init_task_entry);
-    kernel_task("disk", disk_task_entry);
-    kernel_task("user", user_task_entry);
+    kernel_task("init", init_task_entry, NULL);
+    kernel_task("disk/0", disk_task_entry, (void *)0);
+    kernel_task("disk/2", disk_task_entry, (void *)2);
+    kernel_task("user", user_task_entry, NULL);
 
     // for (int i = 0; i < 100; i++) {
     //     asm("hlt;");
     // }
 
-    kernel_task("tskA", taskA_entry);
-    kernel_task("tskB", taskB_entry);
-    kernel_task("tskC", taskC_entry);
+    kernel_task("tskA", taskA_entry, NULL);
+    kernel_task("tskB", taskB_entry, NULL);
+    kernel_task("tskC", taskC_entry, NULL);
 
     current->priority = 1;
     while (1) {
index 3d78ab7b6f7057bdf2905298ef1714f6ebb9a804..f574aeb9c7cd6042afa403fec2eafc72cbbc7c82 100644 (file)
@@ -22,7 +22,7 @@ const uint32_t PHY_VADDR = 0xB8000;
 const uint32_t VADDR = (uint32_t)pa2va(PHY_VADDR);
 #define TTY_VRAM_SIZE (0x1000)
 
-#define NR_TTYS 8
+#define MAX_NR_TTYS 8
 tty_t ttys[NR_TTYS];
 
 #define MAX_X 80
@@ -67,6 +67,8 @@ void __tty_set_next_pos_color(tty_t *tty, char color) {
 
 void init_tty(tty_t *tty, const char *name, unsigned long base) {
     assert(0 != tty);
+    assert(NR_TTYS >= 1);
+    assert(NR_TTYS <= MAX_NR_TTYS);
 
     strlcpy(tty->name, name, sizeof(tty->name));
 
diff --git a/qemu.sh b/qemu.sh
index c38b3f5dd7cd075204abf5b64994d81bff04d4df..fa9ce4748e6af53364627f76ea96a081a7a56487 100755 (executable)
--- a/qemu.sh
+++ b/qemu.sh
@@ -1,8 +1,9 @@
 qemu-system-i386 \
     -device ich9-ahci,id=ahci \
     -boot d \
-    -drive file=HD.IMG,format=raw,index=0,media=disk \
+    -drive file=HDa.IMG,format=raw,index=0,media=disk \
     -drive file=kernel.iso,index=1,media=cdrom \
+    -drive file=HDb.IMG,format=raw,index=2,media=disk \
     -name kernel \
     -s -S \
     &