From 4cbdbfe838cb791e2e3b782dac79b7512129fe15 Mon Sep 17 00:00:00 2001 From: Ruslan Isaev Date: Sat, 15 Mar 2025 22:33:53 +0300 Subject: [PATCH] disk: implement ata_write --- include/disk.h | 1 + src/disk.c | 36 +++++++++++++++++++++++++++++++----- src/kernel.c | 10 +--------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/disk.h b/include/disk.h index 72f1f01..2635909 100644 --- a/include/disk.h +++ b/include/disk.h @@ -12,5 +12,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); +void ata_write(uint8_t *buffer, uint32_t lba); #endif diff --git a/src/disk.c b/src/disk.c index 8b43937..180959b 100644 --- a/src/disk.c +++ b/src/disk.c @@ -33,6 +33,15 @@ unsigned short ide_read_data() { #define inw ide_read_data +void outw(uint16_t port, uint16_t value) //implemented in asm +{ + __asm__ volatile( + "out %0, %1" + : + : "a" (value), "Nd" (port) + ); +} + unsigned char ide_read_status() { unsigned char status; __asm__ __volatile__("inb %1, %0" : "=a" (status) : "d" (IDE_STATUS)); @@ -154,21 +163,38 @@ void ata_poll() //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(0x1F6, 0xE0 | ((lba >> 24) & 0x0F));//E0 is for master, F0 is for slave + //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(); } + +void ata_write(uint8_t *buffer, uint32_t lba) +{ + outb(0x1F6, 0xE0 | ((lba >> 24) & 0x0F)); + + outb(0x1F2, 1);//sector count + outb(0x1F3, (unsigned char) lba); + outb(0x1F4, (unsigned char) (lba >> 8)); + outb(0x1F5, (unsigned char) (lba >> 16)); + outb(0x1F7, 0x30); //Send the "WRITE SECTORS" command + ata_poll(); + + for(int i = 0; i < 256; i++) + { + uint16_t data = *(uint16_t*)(buffer + i * 2); + outw(0x1F0, data); + ata_400ns_delay(); + } + outb(0x1F7, 0xE7);//Cache flush +} diff --git a/src/kernel.c b/src/kernel.c index e8123ad..f161a37 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -4,6 +4,7 @@ #include "../include/stdio.h" #include "../include/utils.h" #include "../include/disk.h" +#include "../include/string.h" #include @@ -17,20 +18,11 @@ void kmain() char yooo[256] = "heheh"; printf("test string: %s\n", yooo); - 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)