#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()
{
// 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.
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)
{
}
-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)
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
#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);
--- /dev/null
+#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
#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 )
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");