diff --git a/Makefile b/Makefile index 435e4cb..cb436b1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CFLAGS = -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-le LDFLAGS = DISK_IMG_FILES = kernel.bin hello.bin print.bin boot32.bin kernel32.bin -KERNEL32_OBJS = screenstuff.o io.o idt.o keyboard.o strings.o kernel32_strap.o kernel32.o +KERNEL32_OBJS = screenstuff.o io.o idt.o keyboard.o strings.o atapio.o kernel32_strap.o kernel32.o run: disk.img qemu-system-x86_64 disk.img diff --git a/atapio.c b/atapio.c new file mode 100644 index 0000000..a24765b --- /dev/null +++ b/atapio.c @@ -0,0 +1,122 @@ +#include "atapio.h" + +// Disk code + +// Primary ATA Bus: 0x1f0 to 0x1f7 +// Device Control Register: 0x3f6 +// Secondary ATA Bus: 0x170 to 0x177 +// Device Control Register: 0x376 + + +uint16_t identify_result[256]; +uint32_t total_28_lbas = 0; + +uint8_t* rootDirEntries = 0x1000000; +uint16_t* FAT1 = 0x1002000; + +uint16_t countReserved; +uint8_t countFATs; +uint16_t countRDEs; +uint16_t sectorsPerFAT; + + +void init_atapio() { + countReserved = *(uint16_t*)0x7c0e; + countFATs = *(uint8_t*)0x7c10; + countRDEs = *(uint16_t*)0x7c11; + sectorsPerFAT = *(uint16_t*)0x7c16; + + // Select Drive 0 on the Primary Bus + outb(0x1f6, 0xa0); + + // Set sector count to 0 for IDENTIFY + outb(0x1f2, 0); + // Set LBAlo to 0 + outb(0x1f3, 0); + // Set LBAmid to 0 + outb(0x1f4, 0); + // Set LBAhi to 0 + outb(0x1f5, 0); + + // Send IDENTIFY command + outb(0x1f7, 0xec); + + uint8_t status = inb(0x1f7); + if (status) { + while ((status = inb(0x1f7)) & 0x80); + + if ( !(inb(0x1f4) || inb(0x1f5)) ) { + while ( !(status & 8 || status & 1) ) + status = inb(0x1f7); + + if (!(status & 1)) { + for (int index=0; index<256; index++) + identify_result[index] = inw(0x1f0); + } + } + } + + total_28_lbas = *(uint32_t*)(identify_result+60); + + // We've initialised now, let's load the FAT and RootDirEntries. + read_sectors(sectorsPerFAT * countFATs + 1, countRDEs / 16, rootDirEntries); + read_sectors(1, sectorsPerFAT, FAT1); +} + +void read_sector(uint32_t address, uint8_t* buffer) { + outb(0x1f6, 0xe0 | ((address>>24)&0x0f)); + // Read a single sector + outb(0x1f2, 1); + // Set LBAlo, LBAmid and LBAhi + outb(0x1f3, address); + outb(0x1f4, address>>8); + outb(0x1f5, address>>16); + + // Send read command + outb(0x1f7, 0x20); + // Poll + uint8_t status = inb(0x1f7); + while ( (status & 0x80) && !(status & 8) ) + status = inb(0x1f7); + + for (int index=0; index<256; index++) + ((uint16_t*)buffer)[index] = inw(0x1f0); +} + +void read_sectors(uint32_t address, int count, uint8_t* buffer) { + for (int i=0; i + +#include "io.h" +#include "types.h" +#include "strings.h" +#include "screenstuff.h" + +void init_atapio(); +void read_sector(uint32_t address, uint8_t* buffer); +void read_sectors(uint32_t address, int count, uint8_t* buffer); +uint16_t file_exists(char* filename); +void load_file(char* filename, uint8_t* location); + +#endif \ No newline at end of file diff --git a/kernel32.c b/kernel32.c index 6fc3b6b..05fc4ed 100644 --- a/kernel32.c +++ b/kernel32.c @@ -3,8 +3,8 @@ #include "io.h" #include "idt.h" #include "keyboard.h" - #include "strings.h" +#include "atapio.h" int main() { init_idt(); @@ -16,6 +16,18 @@ int main() { init_keyboard(); enable_idt(); + init_atapio(); + + uint8_t sector[512]; + + read_sector(0, sector); + + printf("OEM ID: %s\n", (char*)(sector+0x3)); + + char hellotxt[1024]; + + load_file("HELLO TXT", hellotxt); + printf("%s", hellotxt); while (1) { @@ -32,12 +44,12 @@ int main() { printf( "XnoeOS 32 Bit Mode Help.\n" "------------------------\n" - "- help\n" - ": Shows this message\n" - "- clear\n" - ": Clears the screen\n" + " - help\n" + " : Shows this message\n" + " - clear\n" + " : Clears the screen\n" " - echo\n" - ": Repeats the text written afterwards\n" + " : Repeats the text written afterwards\n" ); } else if (strcmp(buffer, "clear", 5)) { clear_screen();