From 16af4746ae5058ab066dc1ccdcd6e69ec00d73d3 Mon Sep 17 00:00:00 2001 From: notsomeidiot123 Date: Mon, 29 Sep 2025 11:05:26 -0400 Subject: [PATCH] Finished ATA driver --- initrc.conf | 2 +- src/kernel/drivers/ustar.c | 2 +- src/kernel/kmain.c | 12 +---- src/kmodules/disk_driver.c | 92 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/initrc.conf b/initrc.conf index 8611be3..936f9ac 100644 --- a/initrc.conf +++ b/initrc.conf @@ -2,4 +2,4 @@ ECHO "Initrc for Kimi's OS" MODULE boot/idm.elf MODULE boot/ifsm.elf # This is a comment -END # does nothing but make the whole thing slightly more efficient +END # does nothing but make the whole thing slightly more efficient ( stops before end of file's page) diff --git a/src/kernel/drivers/ustar.c b/src/kernel/drivers/ustar.c index 2b91eff..0ec5dcf 100644 --- a/src/kernel/drivers/ustar.c +++ b/src/kernel/drivers/ustar.c @@ -28,7 +28,7 @@ int read_initrd(initrd_t *initrd){ // return filesize; // } // printf("size: %d", sizeof(USTAR_file_t)); - uint32_t fsize_pgs = (((filesize + 4095)/4096) + 1); + uint32_t fsize_pgs = (((filesize + 4095)/4096)); // uint32_t *ptr = kmalloc(fsize_pgs); // for(uint32_t i = 0; i < (filesize/4) + 1; i++){ // ptr[i] = ((uint32_t *)(archive + offset + sizeof(USTAR_file_t)))[i]; diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 2083278..abd717c 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -29,17 +29,7 @@ void sysinit(){ } modules_init(); initrc_read(initrc); - // uint8_t *buffer = kmalloc(1); - // int status = fread(drive_test, buffer, 0, 4096); - // if(status == -1){ - // printf("Error reading drive\n"); - // for(;;); - // } - // for(uint32_t i = 0; i < 512; i++){ - // printf("%c", buffer[i]); - - // } - //fopen shell file & execute it. + printf("Bleh\n"); for(;;); } diff --git a/src/kmodules/disk_driver.c b/src/kmodules/disk_driver.c index be4060f..fbb6626 100644 --- a/src/kmodules/disk_driver.c +++ b/src/kmodules/disk_driver.c @@ -188,9 +188,96 @@ uint32_t find_free_drive(){ } } +int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){ + if (count == 0) return -1; + + drive_t drive = drives[file->mount_id]; + uint16_t io_base = drive.BARs[0] >> 2; + uint16_t ctrl_base = drive.BARs[1] >> 2; + uint16_t bm_base = drive.BARs[4] & ~3; + + + PRD_T *prdt = drive.PRDT; + uint32_t pages = (count + 4095) / 4096; + + uint32_t sector_count = pages*8; + api(MODULE_API_PRINT, MODULE_NAME, "pages: %x, scount: %x\n", pages, sector_count); + if (sector_count == 0) return -1; + for (uint32_t i = 0; i < pages; i++) { + prdt[i].address = api(MODULE_API_PADDR, ptr + (i << 12)); + // api(MODULE_API_PRINT, MODULE_NAME, "ADDR: %x, Count: %x", ptr + (i << 12), api(MODULE_API_PADDR, prdt)); + prdt[i].byte_count = 4096; + api(MODULE_API_PRINT, MODULE_NAME, "ADDR: %x, Count: %x\n", prdt[i].address, prdt[i].byte_count); + prdt[i].reserved = 0; + if(i == pages - 1){ + prdt[i].reserved = 0x8000; + api(MODULE_API_PRINT, MODULE_NAME, "Reserved: %x\n", prdt[i].reserved); + } + } + + outb(ctrl_base, 0x00); + outb(bm_base + 2, 0x06); + outl(bm_base + 4, api(MODULE_API_PADDR, prdt)); + uint32_t test = inl(bm_base + 4); + api(MODULE_API_PRINT, MODULE_NAME, "PRDT (Read back from busmaster): %x\n", test); + outb(bm_base, 0x00); + + while(!ata_ready(io_base, ctrl_base, drive.flags.slave << 4)); + uint64_t lba = offset >> 9; + // uint64_t lba = 0; + outb(io_base + ATA_DRIVE_HEAD, 0x40 | (drive.flags.slave << 4) | ((lba >> 24) & 0x0F)); + + if (drive.flags.huge) { + // 48-bit LBA (use READ_DMA_EXT) + outb(io_base + ATA_SECTOR_COUNT, sector_count >> 8); + outb(io_base + ATA_LBA_LOW, (lba >> 24) & 0xFF); + outb(io_base + ATA_LBA_MID, (lba >> 32) & 0xFF); + outb(io_base + ATA_LBA_HIH, (lba >> 40) & 0xFF); + outb(io_base + ATA_SECTOR_COUNT, sector_count & 0xFF); + outb(io_base + ATA_LBA_LOW, lba & 0xFF); + outb(io_base + ATA_LBA_MID, (lba >> 8) & 0xFF); + outb(io_base + ATA_LBA_HIH, (lba >> 16) & 0xFF); + uint32_t volatile status = inb(io_base + ATA_STATUS); + while(status & 0x80 || !(status & 0x40)) status = inb(io_base + ATA_STATUS); + outb(io_base + ATA_COMMAND, ATA_CMD_WRITE_DMA_EXT); + } else { + // 28-bit LBA (use READ_DMA) + outb(io_base + ATA_SECTOR_COUNT, sector_count); + outb(io_base + ATA_LBA_LOW, lba & 0xFF); + outb(io_base + ATA_LBA_MID, (lba >> 8) & 0xFF); + outb(io_base + ATA_LBA_HIH, (lba >> 16) & 0xFF); + uint32_t volatile status = inb(io_base + ATA_STATUS); + while(status & 0x80 || !(status & 0x40)) status = inb(io_base + ATA_STATUS); + outb(io_base + ATA_COMMAND, ATA_CMD_WRITE_DMA); + } + expected_ints = pages; + recieved_ints = 0; + + + outb(bm_base, 0x01); + + transferring_disk_index = file->mount_id; + + uint8_t status = inb(ctrl_base); + uint8_t bm_status = inb(bm_base + 2); + api(MODULE_API_PRINT, MODULE_NAME, "Status: (ATA)%x, (Busmaster)%x\n", status, bm_status); + // if(ATA_ABRT(status)){ + // puts(api, MODULE_NAME, "Command aborted\n"); + // return -1; + // } + + // while (transferring_disk_index != -1); + while(ATA_BSY(status)){ + status = inb(io_base + ATA_STATUS); + } + outb(bm_base, 0x00); + + return 0; +} + int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count) { if (count == 0) return -1; - + drive_t drive = drives[file->mount_id]; uint16_t io_base = drive.BARs[0] >> 2; uint16_t ctrl_base = drive.BARs[1] >> 2; @@ -296,9 +383,6 @@ cpu_registers_t *int_handler(cpu_registers_t * regs){ } -int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){ - -} //dma set 0x80 for udma //