From ea39cb85f31bd020f91a8d2236529597595176bc Mon Sep 17 00:00:00 2001 From: Ruslan Isaev Date: Thu, 14 Aug 2025 21:13:10 +0300 Subject: [PATCH] add atapi driver --- Makefile | 12 ++++- include/atapi.h | 9 ++++ src/drivers/atapi.c | 94 +++++++++++++++++++++++++++++++++ src/kernel/kernel.c | 123 +++----------------------------------------- 4 files changed, 120 insertions(+), 118 deletions(-) create mode 100644 include/atapi.h create mode 100644 src/drivers/atapi.c diff --git a/Makefile b/Makefile index dd2518b..3599bbe 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o \ bin/utils.o bin/string.o bin/stdio.o bin/disk.o bin/pic.o bin/pit.o \ bin/keyboard.o bin/paging.o bin/page_alloc.o bin/page_tables.o \ bin/fat.o bin/task.o bin/switch.o bin/sys_exit.o bin/gdt.o bin/isr-asm.o \ - bin/kheap.o bin/liballoc.o bin/exec_from_file.o bin/syscalls.o + bin/kheap.o bin/liballoc.o bin/exec_from_file.o bin/syscalls.o bin/atapi.o # Define the compiler and assembler #CC = i686-elf-gcc -D__is_katauos @@ -50,6 +50,13 @@ image: sudo umount /mnt sudo losetup -D +iso: + cp katauos.bin grubshit/boot + grub-mkrescue -o boot.iso grubshit/ + +test-cdrom: + qemu-system-i386 -cdrom boot.iso -m 4096M -d int + test: qemu-system-i386 -drive file=boot.iso,media=disk,format=raw -m 4096M -d int @@ -140,6 +147,9 @@ bin/exec_from_file.o: src/tasking/exec_from_file.c bin/syscalls.o: src/tasking/syscalls.c $(CC) $(CFLAGS) -c $< -o $@ +bin/atapi.o: src/drivers/atapi.c + $(CC) $(CFLAGS) -c $< -o $@ + clean: rm -rf bin/ rm -f $(OUTPUT) diff --git a/include/atapi.h b/include/atapi.h new file mode 100644 index 0000000..80b8d33 --- /dev/null +++ b/include/atapi.h @@ -0,0 +1,9 @@ +#ifndef ATAPI_H +#define ATAPI_H + +#include +#include + +int read_cdrom(uint16_t port, bool slave, uint32_t lba, uint32_t sectors, uint16_t *buffer); + +#endif \ No newline at end of file diff --git a/src/drivers/atapi.c b/src/drivers/atapi.c new file mode 100644 index 0000000..3c69ae9 --- /dev/null +++ b/src/drivers/atapi.c @@ -0,0 +1,94 @@ +#include "../include/atapi.h" +#include "../include/utils.h" + +// Handy register number defines +#define DATA 0 +#define ERROR_R 1 +#define SECTOR_COUNT 2 +#define LBA_LOW 3 +#define LBA_MID 4 +#define LBA_HIGH 5 +#define DRIVE_SELECT 6 +#define COMMAND_REGISTER 7 + +// Control register defines +#define CONTROL 0x206 + +#define ALTERNATE_STATUS 0 + +static __inline void insw(uint16_t __port, void *__buf, unsigned long __n) +{ + __asm__ __volatile__("cld; rep; insw" + : "+D"(__buf), "+c"(__n) + : "d"(__port)); +} + +static __inline__ void outsw(uint16_t __port, const void *__buf, unsigned long __n) +{ + __asm__ __volatile__("cld; rep; outsw" + : "+S"(__buf), "+c"(__n) + : "d"(__port)); +} + +// This code is to wait 400 ns +static void ata_io_wait(const uint8_t p) +{ + inportb(p + CONTROL + ALTERNATE_STATUS); + inportb(p + CONTROL + ALTERNATE_STATUS); + inportb(p + CONTROL + ALTERNATE_STATUS); + inportb(p + CONTROL + ALTERNATE_STATUS); +} + +// Reads sectors starting from lba to buffer +int read_cdrom(uint16_t port, bool slave, uint32_t lba, uint32_t sectors, uint16_t *buffer) +{ + // The command + volatile uint8_t read_cmd[12] = {0xA8, 0, + (lba >> 0x18) & 0xFF, (lba >> 0x10) & 0xFF, (lba >> 0x08) & 0xFF, + (lba >> 0x00) & 0xFF, + (sectors >> 0x18) & 0xFF, (sectors >> 0x10) & 0xFF, (sectors >> 0x08) & 0xFF, + (sectors >> 0x00) & 0xFF, + 0, 0}; + + outportb(port + DRIVE_SELECT, 0xA0 & (slave << 4)); // Drive select + ata_io_wait(port); + outportb(port + ERROR_R, 0x00); + outportb(port + LBA_MID, 2048 & 0xFF); + outportb(port + LBA_HIGH, 2048 >> 8); + outportb(port + COMMAND_REGISTER, 0xA0); // Packet command + ata_io_wait(port); // I think we might need this delay, not sure, so keep this + + // Wait for status + while (1) + { + uint8_t status = inportb(port + COMMAND_REGISTER); + if ((status & 0x01) == 1) + return 1; + if (!(status & 0x80) && (status & 0x08)) + break; + ata_io_wait(port); + } + + // Send command + outsw(port + DATA, (uint16_t *)read_cmd, 6); + + // Read words + for (uint32_t i = 0; i < sectors; i++) + { + // Wait until ready + while (1) + { + uint8_t status = inportb(port + COMMAND_REGISTER); + if (status & 0x01) + return 1; + if (!(status & 0x80) && (status & 0x08)) + break; + } + + int size = inportb(port + LBA_HIGH) << 8 | inportb(port + LBA_MID); // Get the size of transfer + + insw(port + DATA, (uint16_t *)((uint8_t *)buffer + i * 0x800), size / 2); // Read it + } + + return 0; +} \ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index b21397b..3c77cca 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -13,125 +13,10 @@ #include "../include/liballoc.h" #include "../include/kheap.h" #include "../include/exec_from_file.h" +#include "../include/atapi.h" #include -disk_ops_t ops = -{ - .read = ata_read, - .write = ata_write, -}; - -static fat_t g_fat; -static const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - -static int cat(const char* path) -{ - file_t file; - int err = fat_fopen(&file, path, "r"); - if (err) - return err; - - uint8_t buf[512]; - for (;;) - { - int cnt = fat_fread(&file, buf, 512); - if (cnt < 0) - return cnt; - - printf("%.*s\n", cnt, buf); - printf("%s\n", buf); - if (cnt < 512) - break; - } - - return fat_fclose(&file); -} - -static int ls(const char* path) -{ - dir_t dir; - dir_info_t info; - - int err = fat_opendir(&dir, path); - if (err) - return err; - - for (;;) - { - err = fat_readdir(&dir, &info); - if (err == FAT_ERR_EOF) - return FAT_ERR_NONE; - if (err) - return err; - - printf("%X %s %x %x:%x %x %s%c\n", - info.size, months[info.modified.month], info.modified.day, - info.modified.hour, info.modified.min, - info.namelen, info.name, info.attr & FAT_ATTR_DIR ? '/' : ' '); - - err = fat_nextdir(&dir); - if (err) - return err; - } -} - -void test(int err, const char* huy) -{ - if(err != 0) - printf("ERROR: %X %s\n", err, huy); - else - printf("%s done", huy); -} - -void file_fuckery() -{ - int err, cnt; - err = fat_mount(&ops, 0, &g_fat, "ebalo"); - - if(err) - printf("KATYAKATYAKATYAKATYAKATYA: %X\n", err); - - printf("%X\n", err); - - err = ls("/ebalo"); - printf("\n\n\n"); - err = fat_mkdir("/ebalo/numbers"); - err = fat_mkdir("/ebalo/numbers/nigga"); - printf("MKDIR ERR: %X\n", err); - - err = fat_unlink("/ebalo/numbers/nigga/"); - printf("UNLINK ERR: %X\n", err); - - err = fat_unlink("/ebalo/numbers/"); - printf("UNLINK ERR: %X\n", err); - - /*err = fat_mkdir("/ebalo/numbers"); - //err = cat("/ebalo/boot/grub/grub.cfg"); - char *filenames[] = {"/ebalo/numbers/d","/ebalo/numbers/e"}; - for(int i = 0; i < 2; i++){ - printf(filenames[i]); - file_t file; - err = fat_fopen(&file, filenames[i], "w"); - if (err) - {printf("1 err %X\n", err); goto unmount;} - - for (int i = 0; i < 10; i++) - { - cnt = fat_fprintf(&file, "This is test number %d\n", i); - if (cnt < 0) - {printf("2 cnt: %X\n", cnt); goto unmount;} - } - - err = fat_fclose(&file); - } -*/ -unmount: - printf("err%X\n", err); - err = fat_umount(&g_fat); - test(err, "unmount"); -} - void apply_pic_masks() { //0x21 is master pic, 0xa1 is slave pic @@ -218,7 +103,11 @@ void kmain(unsigned int magic, unsigned int info) printf("huy1 points to: 0x%X huy2 points to:0x%X\n", huy, huy2); printf("huy1: %s\nhuy2: %s", huy, huy2); - exec_from_file("/ebalo/main", "/ebalo/"); + uint8_t buffer[2048]; + + read_cdrom(0x170, false, 1230, 1, (uint16_t*)buffer); + printf("buffer:\n %s\n", buffer); + //exec_from_file("/ebalo/main", "/ebalo/"); while(1) {