]> Zhao Yanbai Git Server - kernel.git/commitdiff
add read disk partition code
authorAceVest <zhaoyanbai@126.com>
Sat, 5 Jul 2014 07:33:34 +0000 (15:33 +0800)
committerAceVest <zhaoyanbai@126.com>
Sat, 5 Jul 2014 07:33:34 +0000 (15:33 +0800)
drivers/ide.c
drivers/ide.h
include/system.h
kernel/clock.c
kernel/setup.c
kernel/system.c
lib/vsprintf.c

index ed84e578ce7b9fed0443b13a5caaf31d900ed571..03c5340c28b81c9d30188925ba683a78c588a559 100644 (file)
@@ -37,6 +37,10 @@ typedef struct _ide_drv
     unsigned int bus_prdt;
 
     unsigned int read_mode;
+
+
+    u64_t   ext_lba_base;
+    part_t  part[MAX_SUPPORT_PARTITION_CNT];
 } ide_drive_t;
 
 ide_drive_t drv;
@@ -51,6 +55,10 @@ typedef struct prd
 
 unsigned char *data = 0;
 
+unsigned int sys_clock();
+
+bool ide_init_inted = false;
+
 void ide_pci_init(pci_device_t *pci)
 {
     unsigned int v;
@@ -97,13 +105,15 @@ void ide_printd()
 
 void _ide_cmd_out(dev_t dev, u32 sect_cnt, u64 sect_nr, u32 cmd, bool pio)
 {
+    ide_init_inted = false;
+
     drv.pio_cnt++;
     drv.read_mode = cmd;
 
     ide_printd();
 
     outb(0x00|(pio?0:HD_CTL_NIEN),  REG_CTL(dev));
-    outb(0x40|0x10,                 REG_DEVSEL(dev));
+    outb(0x40|0x00,                 REG_DEVSEL(dev));
 
     outb((u8)((sect_cnt>>8)&0xFF),  REG_NSECTOR(dev));    // High
     outb((u8)((sect_nr>>24)&0xFF),  REG_LBAL(dev));
@@ -142,13 +152,6 @@ void ide_cmd_out(dev_t dev, u32 sect_cnt, u64 sect_nr, u32 cmd)
     _ide_cmd_out(dev, sect_cnt, sect_nr, cmd, true);
 }
 
-void ide_wait_read(dev_t dev, u32 sect_cnt, u64 sect_nr, char *buf)
-{
-    _ide_cmd_out(dev, sect_cnt, sect_nr, HD_CMD_READ_EXT, false);
-    ide_wait_ready();
-    insl(REG_DATA(dev), buf, (sect_cnt*512)>>2);
-}
-
 void dump_pci_ide();
 
 void ide_status()
@@ -169,7 +172,7 @@ void ide_debug()
 
     nsect    = (count + SECT_SIZE -1)/SECT_SIZE;
 
-    ide_cmd_out(0, nsect,  sect_nr, HD_CMD_READ_EXT);
+    ide_cmd_out(0, nsect, sect_nr, HD_CMD_READ_EXT);
 }
 
 DECLARE_MUTEX(mutex);
@@ -186,8 +189,9 @@ void init_pci_controller(unsigned int classcode)
     }
 }
 
-char buf[1024];
-void ide_irq()
+
+char ide_buf[1024];
+void ide_default_intr()
 {
     u8_t status = inb(REG_STATUS(0));
 
@@ -206,8 +210,8 @@ void ide_irq()
     u16_t sig = 0;
     if(drv.read_mode == HD_CMD_READ_EXT)
     {
-        insl(REG_DATA(0), buf, (512>>2));
-        sig = *((u16_t *) (buf+510));
+        insl(REG_DATA(0), ide_buf, (512>>2));
+        sig = *((u16_t *) (ide_buf+510));
     }
 
     if(drv.read_mode == HD_CMD_READ_DMA)
@@ -224,6 +228,13 @@ void ide_irq()
     up(&mutex);
 }
 
+typedef void (*ide_intr_func_t)();
+ide_intr_func_t ide_intr_func = ide_default_intr;
+
+void ide_irq()
+{
+    ide_intr_func();
+}
 
 void print_ide_identify(const char *buf)
 {
@@ -284,8 +295,8 @@ void ide_read_identify()
 
     ide_wait_ready();
 
-    insl(REG_DATA(0), buf, 512>>2);
-    print_ide_identify(buf);
+    insl(REG_DATA(0), ide_buf, 512>>2);
+    print_ide_identify(ide_buf);
 }
 
 prd_t prd __attribute__((aligned(64*1024)));
@@ -300,6 +311,7 @@ unsigned long gprdt = 0;
 
 void ide_dma_pci_lba48()
 {
+    ide_init_inted = false;
     drv.dma_cnt ++;
     drv.read_mode = HD_CMD_READ_DMA;
 #if 1
@@ -386,64 +398,179 @@ typedef struct {
     unsigned int sect_cnt;
 } hd_part_t ;
 
-#if 1
-void spartition(u64_t sect_nr, u64_t base)
+
+
+char *ide_init_buf = 0;
+void ide_init_intr()
 {
-    base += sect_nr;
-    printk("SECT NR %d\n", sect_nr);
-    char *part_buf=kmalloc(1024, 0);
-    ide_wait_read(0, 1, base, part_buf);
+    drv.irq_cnt++;
 
-    hd_part_t *p = (hd_part_t *)(part_buf+PARTITION_TABLE_OFFSET);
-    int i;
-    u64_t ext = ~0UL;
-    for(i=0; i<4; ++i)
+    u8_t status = inb(REG_STATUS(0));
+
+    insl(REG_DATA(0), ide_init_buf, (512>>2));
+
+    ide_init_inted = true;
+}
+
+void ide_init_wait_intr()
+{
+    unsigned int clock_end = sys_clock() + 1000;
+
+    while(!ide_init_inted)
+    {
+        if(sys_clock() > clock_end)
+            panic("read hard disk timeout");
+    }
+}
+
+void ide_init_wait_read(u64 lba, char *buf)
+{
+    ide_init_buf = buf;
+    _ide_cmd_out(0, 1, lba, HD_CMD_READ_EXT, true);
+    ide_init_wait_intr();
+}
+
+#if 0
+void ide_read_partition(u64_t lba, bool extended)
+{
+    unsigned int i;
+    char *buf = kmalloc(512, 0);
+    if(buf == 0)
+        panic("no memory");
+
+    ide_init_wait_read(lba, buf);
+
+    u16_t sig = *((u16_t *) (buf+510));
+    if(sig != 0xAA55)
+        panic("bad partition sect");
+
+    hd_part_t *p = (hd_part_t *)(buf+PARTITION_TABLE_OFFSET);
+    printk("-------------------------\n");
+    for(i=0; i<PARTITION_CNT; ++i, ++p)
     {
         if(p->type == 0)
             continue;
-        printk(" Partition[%d] [%02x] LBA %d SectCnt %d\n", i, p->type, (unsigned int)(base+p->lba), (unsigned int)(base+p->lba+p->sect_cnt));
+
+        u64_t   part_lba    = p->lba;       // TODO
+        u64_t   part_scnt   = p->sect_cnt;
+
+        if(p->type == 0x05)
+            printk(" Partition[%d] [%02x] LBA %d %d\n", i, p->type, (unsigned int)part_lba, (unsigned int)((extended?drv.ext_lba_base:0)+part_lba));
+        else
+            printk(" Partition[%d] [%02x] LBA %d %d\n", i, p->type, (unsigned int)part_lba, (unsigned int)(lba+part_lba));
+
         if(p->type == 0x05)
-            ext = p->lba;
+        {
+            if(drv.ext_lba_base == 0)
+                drv.ext_lba_base =part_lba; 
+
 
-        p++;
+            ide_read_partition(part_lba+(extended?drv.ext_lba_base:0), true);
+        }
     }
 
-    printk("--------------------------------------------------%d\n", ext);
-    if(ext != ~0UL)
-        spartition(ext, base);
+    kfree(buf);
 }
 #endif
 
-static int f = 0;
-void partition(u64_t base)
+void ide_read_extended_partition(u64_t lba, unsigned int inx)
 {
-    char *part_buf = kmalloc(1024, 0);
-    ide_wait_read(0, 1, base, part_buf);
+    unsigned int i;
+    char *buf = kmalloc(512, 0);
+    if(buf == 0)
+        panic("no memory");
 
-    hd_part_t *p = (hd_part_t *)(part_buf+PARTITION_TABLE_OFFSET);
+    ide_init_wait_read(lba, buf);
 
-    u16_t sig = *((u16_t *) (part_buf+510));
-    //printk("---------------------------------------------%d    [%04x]\n", x, sig);
-    printk("---------------------------------------------<%d> \n", (unsigned int) base);
+    u16_t sig = *((u16_t *) (buf+510));
+    if(sig != 0xAA55)
+        panic("bad partition sect");
 
-    int i;
-    for(i=0; i<4; ++i)
+    hd_part_t *p = (hd_part_t *)(buf+PARTITION_TABLE_OFFSET);
+    //printk("-------------------------%d \n", lba);
+
+    for(i=0; i<PARTITION_CNT; ++i, ++p)
+    {
+        if(p->type == 0)
+            continue;
+
+        u64_t   part_lba = lba + p->lba;       // TODO
+        u64_t   part_scnt   = p->sect_cnt;
+
+        if(p->type != 0x05)
+        {
+            drv.part[inx].lba_start  = part_lba;
+            drv.part[inx].lba_end    = part_lba+part_scnt;
+            printk("  Logic Partition[%02d] [%02x] LbaBase %10d LbaEnd %10d\n", inx, p->type, (unsigned int)(drv.part[inx].lba_start), (unsigned int)(drv.part[inx].lba_end - 1));
+        }
+        else
+        {
+            part_lba = drv.ext_lba_base + p->lba;
+            printk("        Extended      [%02x] LbaBase %10d LbaEnd %10d\n", p->type, (unsigned int)(part_lba), (unsigned int)(part_lba+part_scnt - 1));
+            ide_read_extended_partition(part_lba, inx+1);
+        }
+    }
+
+    kfree(buf);
+}
+
+void ide_read_partition()
+{
+    printk("Reading Partitions....\n");
+    unsigned int i;
+    char *buf = kmalloc(512, 0);
+    if(buf == 0)
+        panic("no memory");
+
+    ide_init_wait_read(0, buf);
+
+    u16_t sig = *((u16_t *) (buf+510));
+    if(sig != 0xAA55)
+        panic("bad partition sect");
+
+    hd_part_t *p = (hd_part_t *)(buf+PARTITION_TABLE_OFFSET);
+
+    unsigned int ext_inx = ~0U;
+
+    for(i=1; i<PARTITION_CNT; ++i, ++p)
     {
         if(p->type == 0)
             continue;
-        printk(" Partition[%d] [%02x] LBA %d cnt %d LBABASE %d LBAEND %d\n", i, p->type, p->lba, p->sect_cnt, (unsigned int)(base+p->lba), (unsigned int)(base+p->lba+p->sect_cnt));
+
+        u64_t   part_lba    = p->lba;       // TODO
+        u64_t   part_scnt   = p->sect_cnt;
+
+        drv.part[i].lba_start  = part_lba;
+        drv.part[i].lba_end    = part_lba+part_scnt;
+
 
         if(p->type == 0x05)
         {
-            f++;
-            if(f > 1)
-                partition(p->lba+43008);
-            else
-                partition(p->lba+0);
+            if(drv.ext_lba_base == 0)
+            {
+                drv.ext_lba_base = drv.part[i].lba_start; 
+                ext_inx = i;
+            }
         }
 
-        p++;
+        printk("Primary Partition[%02d] [%02x] LbaBase %10d LbaEnd %10d\n", i, p->type, (unsigned int)(part_lba), (unsigned int)(part_lba+part_scnt - 1));
     }
+
+    kfree(buf);
+
+    if(ext_inx != ~0U)
+        ide_read_extended_partition(drv.part[ext_inx].lba_start, 5);
+}
+
+
+
+void ide_init_partition()
+{
+    ide_intr_func = ide_init_intr;
+
+    ide_read_partition();
+
+    ide_intr_func = ide_default_intr;
 }
 
 void ide_init()
@@ -451,13 +578,11 @@ void ide_init()
     memset((void *)&drv, 0, sizeof(drv));
     init_pci_controller(0x0106);
     init_pci_controller(0x0101);
+
 #if 1
     ide_read_identify();
     ide_printd();
 #endif
-    //spartition(0, 0);
-    partition(0);
 
-    u16_t sig = *((u16_t *) (data+510));
-    printk("IDE_INIT______READ %04x\n", sig);
+    ide_init_partition();
 }
index ef85db4c98bff487c7b46f2417b4699b25738ce5..9f66dd96248d157e9dd6f3e18be5fc344a08200b 100644 (file)
@@ -118,5 +118,11 @@ extern unsigned int HD_CHL1_CTL_BASE;
 #define PCI_IDE_PRDT    4
 
 
-
-#define PARTITION_TABLE_OFFSET  0x1BE
+#define PARTITION_CNT               4
+#define PARTITION_TABLE_OFFSET      0x1BE
+#define MAX_SUPPORT_PARTITION_CNT   16
+
+typedef struct {
+    u64_t   lba_start;
+    u64_t   lba_end;
+} part_t;
index 3dca32f5a44510cfdbbfe8282c84557d3194803b..572cbb210c5b01f34fed97d95063293262079912 100644 (file)
@@ -84,6 +84,7 @@ static inline void free_phys_pages(void *p)
 }
 
 #define panic(msg) do {                                     \
+    asm("cli;");                                            \
     printk("PANIC:\"%s\" file:%s function:%s line:%d\n",    \
         msg, __FILE__, __FUNCTION__, __LINE__);             \
     while(1);                                               \
index 53675c3564115989a043a0e1373ea6c7c7d4ed87..cf9ecaecc808992a574f64f2db8231ada25b3ad9 100644 (file)
 
 static unsigned int jiffies = 0;
 
+unsigned int sys_clock()
+{
+    return jiffies;
+}
+
 void clk_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 {
     jiffies++;
index 4717c07510ecbf60b57ff0d144290eb8618a5908..6d6ac65fe22cbf4e7a37d5cae413c6841c533534 100644 (file)
@@ -95,6 +95,8 @@ void setup_kernel()
 
     printk("%s\n", version);
 
+    open_irq(0);
+
     return;
     while(1); // TODO MODIFY CODE BELOW
 
index f6f4e29375020e6bbc0c3009a1fda0ddcd6e6393..9aeeae02a4cc33d3a7f150b186a771188fb7a510 100644 (file)
@@ -96,7 +96,7 @@ void setup_gate()
 void ide_irq();
 void default_ide_irq_handler(unsigned int irq, pt_regs_t * regs, void *dev_id)
 {
-    printk("default irq handler %d \n", irq);
+    //printk("default irq handler %d \n", irq);
     ide_irq();
 }
 
@@ -132,7 +132,7 @@ void setup_irqs()
             request_irq(i, default_irq_handler,   "default",    "default");
     }
 
-    for(i=0; i<16; i++)
+    for(i=1; i<16; i++)
         open_irq(i);
 
     enable_irq();
index 5514c23f02856aff13b0ae887f0a60aaad0dd65a..35fb9949427ec51487cee602440e6bc57838ceb3 100644 (file)
@@ -63,7 +63,6 @@ int vsprintf(char *buf, const char *fmt, char *args)
             align = ALIGN_LEFT;
             ++fmt;
         }
-        
 
         char char_fill = ' ';
         if(*(fmt) == '0' || *(fmt) == ' ')
@@ -79,7 +78,6 @@ int vsprintf(char *buf, const char *fmt, char *args)
             char_cnt *= 10;
             ++fmt;
         }
-
         char_cnt /= 10;
 
         switch(*fmt)
@@ -107,7 +105,7 @@ int vsprintf(char *buf, const char *fmt, char *args)
     *p = 0;
 }
 
-char    *itoa(char *s, int n)
+char *itoa(char *s, int n)
 {
     int i;
     char tmp[64];
@@ -124,10 +122,9 @@ char    *itoa(char *s, int n)
     }while(n);
     while(i) *s++=tmp[--i];
     *s = 0;
-    
 }
 
-char    *itox(char *s, unsigned int n)
+char *itox(char *s, unsigned int n)
 {
     char *p = s;
     char ch,i,flag = 0;