disk: implement ata_read
This commit is contained in:
@@ -11,5 +11,6 @@ typedef struct {
|
||||
|
||||
void get_disk_info(disk_info *info);
|
||||
int ide_check_disk_present();
|
||||
uint8_t ata_read(uint8_t *buffer, uint32_t lba);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
uint8 inportb(uint16 _port);
|
||||
void outportb(uint16 _port, uint8 _data);
|
||||
|
||||
#define inb inportb
|
||||
#define outb outportb
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+43
@@ -31,6 +31,8 @@ unsigned short ide_read_data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
#define inw ide_read_data
|
||||
|
||||
unsigned char ide_read_status() {
|
||||
unsigned char status;
|
||||
__asm__ __volatile__("inb %1, %0" : "=a" (status) : "d" (IDE_STATUS));
|
||||
@@ -129,3 +131,44 @@ int ide_check_disk_present() {
|
||||
|
||||
return 0; // No disk present
|
||||
}
|
||||
|
||||
void ata_400ns_delay()
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
inb(0x1FC);
|
||||
}
|
||||
|
||||
//polling
|
||||
//just waiting for the drive to be ready to transfer data
|
||||
void ata_poll()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
uint8_t status = inportb(0x1F7);
|
||||
if(!(status & STATUS_BUSY) && (status & STATUS_DRQ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//https://wiki.osdev.org/ATA_PIO_Mode
|
||||
//x86 directions section
|
||||
uint8_t ata_read(uint8_t *buffer, uint32_t lba)
|
||||
{
|
||||
outb(0x1F6, 0xE0 | ((lba >> 24) & 0x0F));
|
||||
outb(0x1F1, 0x00);//TODO: this is probably ignored so could be removed maybe?
|
||||
outb(0x1F2, 1);//1 is sector count, how many sectors are we reading
|
||||
outb(0x1F3, (unsigned char) lba);
|
||||
outb(0x1F4, (unsigned char)(lba >> 8));
|
||||
outb(0x1F5, (unsigned char)(lba >> 16));
|
||||
outb(0x1F7, 0x20); //Send the "READ SECTORS" command
|
||||
//TODO: here we do the polling yo
|
||||
ata_poll();
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
uint16_t data = inw(0x1F0);
|
||||
*(uint16_t*)(buffer+i*2) = data;
|
||||
//printf("data: %X\n", data);
|
||||
}
|
||||
//TODO: give the drive 400ns delay to reset DRQ
|
||||
ata_400ns_delay();
|
||||
}
|
||||
|
||||
+9
-4
@@ -17,15 +17,20 @@ void kmain()
|
||||
|
||||
char yooo[256] = "heheh";
|
||||
printf("test string: %s\n", yooo);
|
||||
|
||||
//printf("checking for disk...\n");
|
||||
//int disk_present = ide_check_disk_present();
|
||||
//printf("we got the result, it's %X\n", disk_present);
|
||||
printf("%X %X %X", 0x11, 0xA, 0xFEE1DEAD);
|
||||
|
||||
disk_info info;
|
||||
get_disk_info(&info);
|
||||
printf("CYL HEAD SECT: %X %X %X\n", info.cylinders, info.heads, info.sectors);
|
||||
|
||||
uint8_t buffer[512];
|
||||
ata_read(buffer, 0x0);
|
||||
|
||||
for(int i = 0; i < sizeof(buffer); i++)
|
||||
{
|
||||
printf("%X ", buffer[i]);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(inportb(0x64) & 0x1)
|
||||
|
||||
Reference in New Issue
Block a user