From: Rhett Aultman Date: Sun, 15 Jul 2012 08:08:28 +0000 (-0700) Subject: Read partitions from main disk X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=ea91e3c409b0dbfbf48f94233c037ef80103f9e2;p=arcanos.git Read partitions from main disk --- diff --git a/kern/Makefrag b/kern/Makefrag index a9ad9d8..fd374eb 100644 --- a/kern/Makefrag +++ b/kern/Makefrag @@ -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)) diff --git a/kern/devices/atapio.c b/kern/devices/atapio.c index 721d0f1..86d31cb 100644 --- a/kern/devices/atapio.c +++ b/kern/devices/atapio.c @@ -2,8 +2,10 @@ #include #include +#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 diff --git a/kern/devices/atapio.h b/kern/devices/atapio.h index bcb0aaa..4f41def 100644 --- a/kern/devices/atapio.h +++ b/kern/devices/atapio.h @@ -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 index 0000000..fb01011 --- /dev/null +++ b/kern/fs/partitions.c @@ -0,0 +1,28 @@ +#include +#include +#include + +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 diff --git a/kern/init.c b/kern/init.c index aac14a7..52ba583 100644 --- a/kern/init.c +++ b/kern/init.c @@ -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");