From c7aaedbd2a55af7d2939708150f5acd52e62fdfd Mon Sep 17 00:00:00 2001 From: notsomeidiot123 Date: Wed, 24 Sep 2025 12:15:52 -0400 Subject: [PATCH] ata_read --- makefile | 6 +- src/kernel/arch_i386/interrupts.c | 4 + src/kernel/kmain.c | 18 +++- src/kernel/shared/interrupts.h | 3 +- src/kernel/system/modules.c | 42 +++++--- src/kernel/system/modules.h | 39 +++---- src/kmodules/disk_driver.c | 165 +++++++++++++++++++++++------- src/kmodules/modlib.h | 46 +++++---- 8 files changed, 233 insertions(+), 90 deletions(-) diff --git a/makefile b/makefile index 025dd35..ba46bb4 100644 --- a/makefile +++ b/makefile @@ -36,7 +36,7 @@ mount: bootloader tools kernel bootloader: $(AS) src/bootloader/main.s $(BL_ASFLAGS) -o bin/bootloader.bin run: - qemu-system-i386 -hda image.bin --no-reboot --no-shutdown -m 32m -smp 2 -serial mon:stdio -D intlog.txt -d int + qemu-system-i386 -hda image.bin -hdb test.bin --no-reboot --no-shutdown -m 32m -smp 2 -serial mon:stdio -D intlog.txt -d int # kernel: $(OBJS) kernel: @@ -48,9 +48,9 @@ kernel: # ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386 ld -T linker.ld bin/kernel/*.o -melf_i386 -o kernel.elf -static ld -T linker.ld -o kernel_interface.elf -r -R kernel.elf -melf_i386 - ld -pie bin/modules/disk_driver.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib + ld -pie bin/modules/disk_driver.o bin/kernel/string.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib # ld bin/modules/fs_driver.o -o ifsm.elf -melf_i386 - ld -pie bin/modules/fs_driver.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib + ld -pie bin/modules/fs_driver.o bin/kernel/string.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib # %.o: $(SRCS) # mkdir -p bin/kernel/$(shell dirname $@) # $(CC) $(CFLAGS) $< -o $@ diff --git a/src/kernel/arch_i386/interrupts.c b/src/kernel/arch_i386/interrupts.c index bce9fa6..378ce83 100644 --- a/src/kernel/arch_i386/interrupts.c +++ b/src/kernel/arch_i386/interrupts.c @@ -118,6 +118,10 @@ void kernel_panic(char *message, cpu_registers_t *regs){ void install_irq_handler(void (*handler)(), uint8_t irqno){ interrupt_handlers[irqno] = handler; + // printf("called\n"); +} +void *get_irq_handler(uint8_t irqno){ + return interrupt_handlers[irqno]; } void pit_reload(uint8_t mode, uint16_t reload){ const uint16_t PIT_CMD = 0x43; diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 44121ab..ea1f47c 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -20,7 +20,19 @@ void sysinit(){ mlog("KERNEL", "PID 1 Started\n", MLOG_PRINT); pci_init(); modules_init(boot_info); - vfile_t *file; + vfile_t *file = fopen("/dev/disk"); + vfile_t **dir_data = file->access.data.ptr; + printf("/dev/disk/: %x\n", file); + // fcreate("/dev/disk/test", VFILE_DEVICE, 0, 0); + int i = 0; + while(dir_data[i]){ + printf("%d: %s\n", i, dir_data[i]->name); + i++; + } + vfile_t *drive_test = fopen("/dev/disk/ide0"); + uint32_t *buffer = kmalloc(1); + int status = fread(drive_test, buffer, 0, 512); + printf("Done: %x, %x\n", status, buffer[0]); //fopen shell file & execute it. for(;;); } @@ -31,10 +43,12 @@ extern void kmain(kernel_info_t *kernel_info){ idt_load(); pic_init(0x20); pic_disable(); - pic_setmask(0xfe, PIC1_DATA); + pic_setmask(0x0, PIC1_DATA); + pic_setmask(0x0, PIC2_DATA); vfs_init(); fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("/dev/disk", VFILE_DIRECTORY, kmalloc(1), 1); fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1); mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT); boot_info = kernel_info; diff --git a/src/kernel/shared/interrupts.h b/src/kernel/shared/interrupts.h index 79a02fd..73aa3a6 100644 --- a/src/kernel/shared/interrupts.h +++ b/src/kernel/shared/interrupts.h @@ -30,4 +30,5 @@ inline void disable_interrupts(){ asm volatile("cli"); } void kernel_panic(char *msg, cpu_registers_t *regs); -void install_irq_handler(void (*handler)(), uint8_t irqno); \ No newline at end of file +void install_irq_handler(void (*handler)(), uint8_t irqno); +void *get_irq_handler(uint8_t irqno); \ No newline at end of file diff --git a/src/kernel/system/modules.c b/src/kernel/system/modules.c index abe1ab7..1900fa1 100644 --- a/src/kernel/system/modules.c +++ b/src/kernel/system/modules.c @@ -19,28 +19,44 @@ uint32_t module_api(uint32_t func, ...){ //do something module_t *structure = va_arg(vars, void *); if(structure == 0){ - return -1; + return_value = -1; } vector_push(modules, structure); uint32_t tmp = pm_alloc(); (structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5; + structure->key & 0xffffff00 | modules->size; pm_free(tmp); - return 0; - break; - case MODULE_API_ADDFUNC: - //do something - return_value = -1; - break; - case MODULE_API_DELFUNC: - //do something - return_value = -1; + return_value = 0; break; case MODULE_API_ADDINT: uint32_t int_index = va_arg(vars, uint32_t); - //do something + uint32_t key = va_arg(vars, uint32_t); + void *interrupt_handler = va_arg(vars, void *); + if(int_index >= 16 || int_index < 0 /* || get_irq_handler(int_index)*/){ + + return_value = -1; + break; + } + // printf("installed %d", int_index); + install_irq_handler(interrupt_handler, int_index); + module_t *tmpmodule = vector_get(key & 0xff, modules); + tmpmodule->interrupts |= 1 << int_index; + return_value = 0; + // printf("Added key\n"); break; case MODULE_API_DELINT: int_index = va_arg(vars, uint32_t); + key = va_arg(vars, uint32_t); + tmpmodule = vector_get(key & 0xff, modules); + if(key == tmpmodule->key){ + install_irq_handler(0, int_index); + tmpmodule->interrupts &= ~(1 << int_index); + } + else{ + return_value = -1; + break; + } + return_value = 0; break; case MODULE_API_PRINT: // vmlog(MODULE_NAME, "Testing modules calling kernel functions\n", MLOG_PRINT, vars); @@ -91,8 +107,8 @@ uint32_t module_api(uint32_t func, ...){ return_value = get_paddr(addr); break; case MODULE_API_MALLOC: - uint32_t size_pgs = va_arg(vars, uint32_t); - return_value = (uint32_t)kmalloc(size_pgs); + uint32_t sz_pgs = va_arg(vars, uint32_t); + return_value = (uint32_t)kmalloc(sz_pgs); break; case MODULE_API_FREE: void *ptr = va_arg(vars, void *); diff --git a/src/kernel/system/modules.h b/src/kernel/system/modules.h index f07e494..0442747 100644 --- a/src/kernel/system/modules.h +++ b/src/kernel/system/modules.h @@ -9,24 +9,27 @@ //no patch number #define MODULE_API_VERSION 0x0100 -#define MODULE_API_REGISTER 0 //registers the module as active using information provided from the module -#define MODULE_API_ADDFUNC 1 //adds function to kernel API handler -#define MODULE_API_DELFUNC 2 //delete function from kernel API handler -#define MODULE_API_ADDINT 3 //set interrupt handler -#define MODULE_API_DELINT 4 //delete interrupt handler -#define MODULE_API_PRINT 5 //print to terminal -#define MODULE_API_READ 6 //read from virtual file -#define MODULE_API_WRITE 7 //write to virtual file -#define MODULE_API_CREAT 8 //create a virtual file and assigns it to the the proper module (requires having a read and write function passed) -#define MODULE_API_DELET 9 //delete a virtual file -#define MODULE_API_OPEN 10 -#define MODULE_API_MAP 11 //map physical address to virtual address -#define MODULE_API_UNMAP 12 //unmap physical address to virtual address -#define MODULE_API_PADDR 13 //get physical address of memory -#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks -#define MODULE_API_FREE 15 //free memory allocated by malloc -#define MODULE_API_PMALLOC64K 16 -#define MODULE_API_KMALLOC_PADDR 17 +enum MODULE_API_FUNCS{ + + MODULE_API_ADDFUNC,//adds function to kernel API handler + MODULE_API_REGISTER, //registers the module as active using information provided from the module + MODULE_API_DELFUNC, //delete function from kernel API handler + MODULE_API_ADDINT, //set interrupt handler + MODULE_API_DELINT, //delete interrupt handler + MODULE_API_PRINT, //print to terminal + MODULE_API_READ, //read from virtual file + MODULE_API_WRITE, //write to virtual file + MODULE_API_CREAT, //create a virtual file and assigns it to the the proper module (requires having a read and write function passed) + MODULE_API_DELET, //delete a virtual file + MODULE_API_OPEN, + MODULE_API_MAP, //map physical address to virtual address + MODULE_API_UNMAP, //unmap physical address to virtual address + MODULE_API_PADDR, //get physical address of memory + MODULE_API_MALLOC, //allocate memory in 4kb blocks + MODULE_API_FREE, //free memory allocated by malloc + MODULE_API_PMALLOC64K, + MODULE_API_KMALLOC_PADDR, +}; typedef struct module{ void *init_entry; diff --git a/src/kmodules/disk_driver.c b/src/kmodules/disk_driver.c index ba7ff85..10411cd 100644 --- a/src/kmodules/disk_driver.c +++ b/src/kmodules/disk_driver.c @@ -127,13 +127,14 @@ void fini(); enum DRIVE_TYPE{ TYPE_NULL, + TYPE_TMP, TYPE_IDE, TYPE_AHCI, TYPE_NVME, TYPE_USB, TYPE_FLOPPY, //Here, Navya, just for you }; - +uint32_t volatile transferring_disk_index = -1; typedef struct drive_desc{ uint32_t BARs[8]; enum DRIVE_TYPE type; @@ -150,10 +151,6 @@ typedef struct drive_desc{ drive_t drives[32] = {0}; -uint16_t get_bus_from_drive(uint32_t drive){ - return drive & 2 ? ATA_SECONDARY_BUS : ATA_PRIMARY_BUS; -} - //return 1 if ready, 0 if not int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){ static uint16_t last_disk = 0; @@ -169,6 +166,7 @@ int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){ uint8_t status = inb(BAR2 ATA_ALT_STATUS); return (status >> 7) == 0; } + void ata_reset(uint16_t bar1){ outw(bar1 ATA_DEVICE_CONTROL, 0x4); for(uint32_t i = 0; i < 4096; i++){ @@ -185,6 +183,89 @@ uint32_t find_free_drive(){ } } +int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count){ + if(count == 0){ + return -1;//prevent from accidentally reading 65536 * 512 bytes + } + + drive_t drive = drives[file->mount_id]; + + uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3); + + uint32_t status = inb(dmabar + 2); + api(MODULE_API_PRINT, MODULE_NAME, "status: %x\n", status); + PRD_T *prdt = drive.PRDT; + if(count == 0) return 0; + uint32_t count_pgs = ((count + 4096) / 4096); + + for(int i = 0; i < count_pgs; i++){ + prdt[i].address = api(MODULE_API_PADDR, ptr + (i * (1 << 12))); + prdt[i].byte_count = (i == (count_pgs - 1)) ? count % (1 << 12) : 1 << 12; + prdt[i].reserved = (1 << 31) * (i == (count_pgs - 1)); + } + outb(dmabar + 2, 0x6); + outl(dmabar + 4, api(MODULE_API_PADDR, prdt)); + outb(dmabar, 0x8); + + while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave)); + + outb(drive.BARs[1], 0x00); + + uint64_t lba = (offset >> 9); + uint8_t *lba_arr = &lba; + outb(drive.BARs[0] + ATA_DRIVE_HEAD, 0x40 | (drive.flags.slave << 4) | ((lba >> 24) * !drive.flags.huge)); + + if(count >> 9 == 0){ + return 0; + } + + if(drive.flags.huge){ + outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) >> 8); + }else{ + outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9)); + } + for(uint32_t i = 0; i < 3; i++){ + outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i + 3 * drive.flags.huge]); + } + if(drive.flags.huge){ + outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) & 0xff); + for(uint32_t i = 0; i < 3; i++){ + outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i]); + } + puts(api, MODULE_NAME, "bleh\n"); + outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA_EXT); + }else{ + outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA); + } + //issue read command to drive + + transferring_disk_index = file->mount_id; + + outb(dmabar, 0x9); + // while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave)); + while(transferring_disk_index != -1); + // while (!(inb(dmabar + 2) & 0x01)); + outb(dmabar, 0x0); + return 0; +} + +cpu_registers_t *int_handler(cpu_registers_t * regs){ + puts(api, MODULE_NAME, "Interrupt called"); + drive_t drive = drives[transferring_disk_index]; + uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3); + uint32_t status = inb(dmabar + 2); + transferring_disk_index = -1; + if(status & 0x4) return regs; + return regs; +} + + +int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){ + +} + + + //return 255 if err/ does not exist //return 0 if is ATA drive //return 1 if is ATAPI @@ -228,24 +309,42 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){ } // drives[index].size_sectors uint32_t lba48 = (identify[83] & (1 << 10)); - drives[index].flags.huge = lba48 ? 1 : 0; + // drives[index].flags.huge = lba48 ? 1 : 0; drives[index].size_sectors = !lba48 ? (identify[60] | (identify[61] << 16)) : ((uint64_t)(identify[100]) | (uint64_t)(identify[101] << 16) | ((uint64_t)identify[102] << 32)); api(MODULE_API_PRINT, MODULE_NAME, "Sector Count: %x\n", drives[index].size_sectors); - + char fname[32]; + strcpy("/dev/disk/ide", fname); + uint8_t ata_drives = 0; + for(uint32_t i = 0; i < 32; i++){ + if(drives[i].type == TYPE_IDE) ata_drives++; + } + drives[index].type = TYPE_IDE; + itoa(ata_drives, fname + strlen(fname), 10); + vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read); + new_file->mount_id = index; + free(api, fname); return 1; } void ide_init(uint32_t BARS[5]){ uint32_t primary_index = find_free_drive(); - drives[primary_index].type = TYPE_IDE; + drives[primary_index].type = TYPE_TMP; + uint32_t primary_slave_index = find_free_drive(); + drives[primary_slave_index].type = TYPE_TMP; uint32_t secondary_index = find_free_drive(); - drives[secondary_index].type = TYPE_IDE; + drives[secondary_index].type = TYPE_TMP; + uint32_t secondary_slave_index = find_free_drive(); + drives[secondary_slave_index].type = TYPE_TMP; for(int i = 0; i < 2; i++){ drives[primary_index].BARs[i] = BARS[i]; + drives[primary_slave_index].BARs[i] = BARS[i]; drives[secondary_index].BARs[i] = BARS[i+2]; + drives[secondary_slave_index].BARs[i] = BARS[i+2]; } drives[primary_index].BARs[4] = BARS[4]; + drives[primary_slave_index].BARs[4] = BARS[4]; drives[secondary_index].BARs[4] = BARS[4]; + drives[secondary_slave_index].BARs[4] = BARS[4]; uint32_t prdt_primary_paddr = api(MODULE_API_PMALLOC64K); uint32_t prdt_secondary_paddr = api(MODULE_API_PMALLOC64K); @@ -253,45 +352,41 @@ void ide_init(uint32_t BARS[5]){ drives[secondary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_secondary_paddr, 16); //now call ATA IDENTIFY uint8_t master_status = ata_identify(primary_index, ATA_MASTER); - drive_t master_copy = drives[primary_index]; - if(ata_identify(primary_index, ATA_SLAVE) == 0){ - if(master_status == -1){ - drives[primary_index].flags.slave = 1; - } - else{ - uint32_t slave_index = find_free_drive(); - drives[slave_index] = drives[primary_index]; - drives[slave_index].flags.slave = 1; - drives[primary_index] = master_copy; - drives[slave_index].type = TYPE_IDE; - } + uint8_t slave_status = ata_identify(primary_slave_index, ATA_SLAVE); + if(master_status){ + drives[primary_index].type = TYPE_NULL; + } + if(slave_status){ + drives[primary_slave_index].type = TYPE_NULL; } master_status = ata_identify(secondary_index, ATA_MASTER); - master_copy = drives[secondary_index]; - if(ata_identify(secondary_index, ATA_SLAVE) == 0){ - if(master_status == -1){ - drives[secondary_index].flags.slave = 1; - } - else{ - uint32_t slave_index = find_free_drive(); - drives[slave_index] = drives[secondary_index]; - drives[slave_index].flags.slave = 1; - drives[secondary_index] = master_copy; - drives[slave_index].type = TYPE_IDE; - } + slave_status = ata_identify(secondary_slave_index, ATA_SLAVE); + if(master_status){ + drives[secondary_index].type = TYPE_NULL; } + if(slave_status){ + drives[secondary_slave_index].type = TYPE_NULL; + } + // outb(BARS[4] >> 1, 0x0); + // int volatile tt = 0; + // while(tt < 50000){ + // tt++; + // } + } void init(KOS_MAPI_FP module_api, uint32_t api_version){ api = module_api; - api(MODULE_API_PRINT, MODULE_NAME, "KIDM Storage Driver Module v0.1.0\nSupported interfaces: \n"); + api(MODULE_API_PRINT, MODULE_NAME, "KIDM Storage Driver Module v0.1.0\nSupported interfaces: \n- PATA\n"); int status = api(MODULE_API_REGISTER, &module_data); if(status){ api(MODULE_API_PRINT, MODULE_NAME, "Failed to register module, exiting\n"); return; } - api(MODULE_API_PRINT, MODULE_NAME, "Key Test: %x", module_data.key); + api(MODULE_API_ADDINT, 15, module_data.key, int_handler); + api(MODULE_API_ADDINT, 14, module_data.key, int_handler); + // api(MODULE_API_ADDINT, 0, module_data.key, int_handler); vfile_t *pci_drive_dir = fopen(api, "/dev/pci/disk/"); vfile_t **dir_data = (pci_drive_dir->access.data.ptr); for(uint32_t i = 0; dir_data[i]; i++){ diff --git a/src/kmodules/modlib.h b/src/kmodules/modlib.h index fd340b3..f150993 100644 --- a/src/kmodules/modlib.h +++ b/src/kmodules/modlib.h @@ -1,24 +1,27 @@ #pragma once #include -#define MODULE_API_REGISTER 0 //registers the module as active using information provided from the module -#define MODULE_API_ADDFUNC 1 //adds function to kernel API handler -#define MODULE_API_DELFUNC 2 //delete function from kernel API handler -#define MODULE_API_ADDINT 3 //set interrupt handler -#define MODULE_API_DELINT 4 //delete interrupt handler -#define MODULE_API_PRINT 5 //print to terminal -#define MODULE_API_READ 6 //read from virtual file -#define MODULE_API_WRITE 7 //write to virtual file -#define MODULE_API_CREAT 8 //create a virtual file and assigns it to the the proper module (requires having a read and write function passed) -#define MODULE_API_DELET 9 //delete a virtual file -#define MODULE_API_OPEN 10 //open a virtual file -#define MODULE_API_MAP 11 //map physical address to virtual address -#define MODULE_API_UNMAP 12 //unmap physical address to virtual address -#define MODULE_API_PADDR 13 //get physical address of memory -#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks -#define MODULE_API_FREE 15 //free memory allocated by malloc -#define MODULE_API_PMALLOC64K 16 //get 64k-aligned pages -#define MODULE_API_KMALLOC_PADDR 17 +enum MODULE_API_FUNCS{ + + MODULE_API_ADDFUNC,//adds function to kernel API handler + MODULE_API_REGISTER, //registers the module as active using information provided from the module + MODULE_API_DELFUNC, //delete function from kernel API handler + MODULE_API_ADDINT, //set interrupt handler + MODULE_API_DELINT, //delete interrupt handler + MODULE_API_PRINT, //print to terminal + MODULE_API_READ, //read from virtual file + MODULE_API_WRITE, //write to virtual file + MODULE_API_CREAT, //create a virtual file and assigns it to the the proper module (requires having a read and write function passed) + MODULE_API_DELET, //delete a virtual file + MODULE_API_OPEN, + MODULE_API_MAP, //map physical address to virtual address + MODULE_API_UNMAP, //unmap physical address to virtual address + MODULE_API_PADDR, //get physical address of memory + MODULE_API_MALLOC, //allocate memory in 4kb blocks + MODULE_API_FREE, //free memory allocated by malloc + MODULE_API_PMALLOC64K, + MODULE_API_KMALLOC_PADDR, +}; typedef uint32_t (*KOS_MAPI_FP)(unsigned int function, ...); typedef struct module{ @@ -31,6 +34,13 @@ typedef struct module{ void (*fini)(void); }module_t; +typedef struct cpu_registers{ + uint32_t gs, fs, es, ds; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + uint32_t int_no, pfa; + uint32_t eip, cs, eflags, useresp, ss; +}__attribute__((packed))cpu_registers_t; + typedef enum vfile_type{ VFILE_POINTER, VFILE_DEVICE,