Read partitions from main disk
authorRhett Aultman <roadriverrail@gmail.com>
Sun, 15 Jul 2012 08:08:28 +0000 (01:08 -0700)
committerRhett Aultman <roadriverrail@gmail.com>
Sun, 15 Jul 2012 08:08:28 +0000 (01:08 -0700)
kern/Makefrag
kern/devices/atapio.c
kern/devices/atapio.h
kern/fs/partitions.c [new file with mode: 0644]
kern/init.c

index a9ad9d84c6216b811783444092b6062acd226cb3..fd374eb85c69919dde05515930deda5dcdf3fda0 100644 (file)
@@ -16,7 +16,8 @@ KERN_SRCFILES :=      kern/entry.S \
                                        kern/interrupts/interrupt_handlers.c \
                                        kern/interrupts/idt.c \
                                        kern/interrupts/pic.c \
-                                       kern/devices/atapio.c
+                                       kern/devices/atapio.c \
+                                       kern/fs/partitions.c
 
 # Only build files if they exist.
 KERN_SRCFILES := $(wildcard $(KERN_SRCFILES))
index 721d0f1a49850db8703ef642bc1e5de5084da8ac..86d31cbe02db408cbd88b7e08b1ef6c50798e2e2 100644 (file)
@@ -2,8 +2,10 @@
 #include <inc/x86.h>
 #include <inc/stringformat.h>
 
+#define RW_DRIVE (0xE0 | slave_bit << 4)
+
 static uint8_t drive_attached = 0;
-static uint8_t current_drive = 0;
+static uint8_t slave_bit = 0;
 
 void atapio_init()
 {
@@ -32,7 +34,7 @@ void atapio_init()
   // disc and let it go
 
   outb(ATA_DEVCONTROL, SELECT_MASTER_DRIVE);
-
+  slave_bit = 0;
   // Drives may need up to 500ns for drive select to
   // complete, and an IO read is about 100ns, so burn
   // 400ns.
@@ -45,7 +47,6 @@ void atapio_init()
   uint8_t cl=inb(ATA_LBAMID_PORT);     /* get the "signature bytes" */
   uint8_t ch=inb(ATA_LBAHI_PORT);
 
-  _kern_print("Read signature bytes %x and %x\n", cl, ch);
   /* differentiate ATA, ATAPI, SATA and SATAPI */
   if (cl==0x14 && ch==0xEB) 
   {
@@ -70,9 +71,9 @@ void atapio_init()
   
 }
 
-void atapio_read(uint32_t sector, uint32_t sector_count, char *buffer)
+void atapio_read(uint32_t sector, uint32_t sector_count, uint16_t *buffer)
 {
-/*
+/* Comment of how to read from http://wiki.osdev.org/ATA_PIO_Mode
 An example of a 28 bit LBA PIO mode read on the Primary bus:
 Send 0xE0 for the "master" or 0xF0 for the "slave", ORed with the highest 4 bits of the LBA to port 0x1F6: outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F))
 Send a NULL byte to port 0x1F1, if you like (it is ignored and wastes lots of CPU time): outb(0x1F1, 0x00)
@@ -86,5 +87,32 @@ Transfer 256 words, a word at a time, into your buffer from I/O port 0x1F0. (In
 Then loop back to waiting for the next IRQ (or poll again -- see next note) for each successive sector.
 */
 
+  outb(ATA_DRIVE_HEAD_PORT, RW_DRIVE | ((sector >> 24) & 0x0F));
+  outb(ATA_FEATURES_ERR_INFO_PORT, 0x00);
+  outb(ATA_SECTOR_COUNT_PORT, sector_count);
+  outb(ATA_LBALOW_PORT, (uint8_t) sector);
+  outb(ATA_LBAMID_PORT, (uint8_t)(sector >> 8));
+  outb(ATA_LBAHI_PORT, (uint8_t)(sector >> 16));
+  outb(ATA_COMMAND_STATUS_PORT, COMMAND_READ_SECTORS);
+
+  while (1)
+  {
+    if ((inb(ATA_COMMAND_STATUS_PORT) & STATUS_BSY) == 0)
+    {
+      break;
+    }
+  }
+  
+  if ((inb(ATA_COMMAND_STATUS_PORT) & STATUS_DRQ) != 0)
+  {
+    for (int i=0; i < 255; i++)
+    {
+      buffer[i] = inw(ATA_DATA_PORT);
+    }
+  } else if ((inb(ATA_COMMAND_STATUS_PORT) & STATUS_ERR) != 0)
+  {
+    _kern_print("Failed to read disk base port: %x slave %x sector %d", base_port, slave_bit, sector);
+  }
 
+  return;
 }
\ No newline at end of file
index bcb0aaab697facefc41008e0a7e83907c68c6821..4f41defba4675cd7e4ebbd994d12f1763b93d3dc 100644 (file)
@@ -52,8 +52,8 @@ uint16_t base_port;
 #define SELECT_MASTER_DRIVE 0xA0
 #define SELECT_SLAVE_DRIVE 0xB0
 
-#define RW_MASTER_DRIVE 0xE0
-#define RW_SLAVE_DRIVE 0xF0
-
 #define COMMAND_READ_SECTORS 0x20
-#define COMMAND_IDENTIFY 0xEC
\ No newline at end of file
+#define COMMAND_IDENTIFY 0xEC
+
+void atapio_init();
+void atapio_read(uint32_t sector, uint32_t sector_count, uint16_t *buffer);
diff --git a/kern/fs/partitions.c b/kern/fs/partitions.c
new file mode 100644 (file)
index 0000000..fb01011
--- /dev/null
@@ -0,0 +1,28 @@
+#include <kern/devices/atapio.h>
+#include <inc/stringformat.h>
+#include <inc/memmgr.h>
+
+void load_partitions()
+{
+  _kern_print("Loading partitions...\n");
+  atapio_init();
+  
+  uint16_t *buffer = memmgr_allocate(512);
+  
+  atapio_read(0, 1, buffer);
+  
+  uint8_t *partition_1 = ((uint8_t *)buffer) + 0x1BE;
+  uint8_t *partition_2 = ((uint8_t *)buffer) + 0x1CE;
+  uint8_t *partition_3 = ((uint8_t *)buffer) + 0x1DE;
+  uint8_t *partition_4 = ((uint8_t *)buffer) + 0x1EE;
+  
+  uint8_t fstype_1 = *(partition_1 + 4);
+  uint8_t fstype_2 = *(partition_2 + 4);
+  uint8_t fstype_3 = *(partition_3 + 4);
+  uint8_t fstype_4 = *(partition_4 + 4);
+  
+  _kern_print("Partition 1 type: %x\n", fstype_1);
+  _kern_print("Partition 2 type: %x\n", fstype_2);
+  _kern_print("Partition 3 type: %x\n", fstype_3);
+  _kern_print("Partition 4 type: %x\n", fstype_4);
+}
\ No newline at end of file
index aac14a765dc3a80745e5293d1555e7663e7a741e..52ba583f0b3e82f148fb545b5dc25b9ed5be0541 100644 (file)
@@ -13,7 +13,7 @@
 #define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
 
 extern void keyboard_isr();
-extern void atapio_init();
+extern void load_partitions();
 void i386_init(multiboot_info_t* mbi);
 
 void kernel_main( void* mbd, unsigned int magic )
@@ -142,7 +142,7 @@ i386_init(multiboot_info_t* mbi)
        memmgr_init();
 
        _kern_print("Initializing ATAPIO driver\n");
-       atapio_init();
+       load_partitions();
 //stop here for now
        _kern_print("Entering kernel idle loop.\n");
        asm("hlt");