diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/image.raw b/image.raw deleted file mode 100644 index f120995..0000000 --- a/image.raw +++ /dev/null @@ -1,2 +0,0 @@ -Hello world this is a test image to see if the disk access will work! -If I can see this message everything seems to have worked :) diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/image.raw b/image.raw deleted file mode 100644 index f120995..0000000 --- a/image.raw +++ /dev/null @@ -1,2 +0,0 @@ -Hello world this is a test image to see if the disk access will work! -If I can see this message everything seems to have worked :) diff --git a/src/include/hardDrive.h b/src/include/hardDrive.h index 819781d..00ada36 100644 --- a/src/include/hardDrive.h +++ b/src/include/hardDrive.h @@ -1,21 +1,44 @@ #ifndef HARD_DRIVE_H #define HARD_DRIVE_H +#define IDE_DATA_REGISTER 0 +#define IDE_ERROR_REGISTER 1 +#define IDE_SECTOR_COUNT_REGISTER 2 +#define IDE_SECTOR_NUMBER_REGISTER 3 +#define IDE_CYLINDER_LOW_REGISTER 4 +#define IDE_CYLINDER_HIGH_REGISTER 5 +// sector size, drive, head +#define IDE_SDH_REGISTER 6 +#define IDE_STATUS_REGISTER 7 +#define IDE_COMMAND_REGISTER 7 +#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 +#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 + +#define IDE_STATUS_BUSY 0x80 +#define IDE_STATUS_READY 0x40 +#define IDE_STATUS_WRITE_FAULT 0x20 +#define IDE_STATUS_SEEK_COMPLETE 0x10 +#define IDE_STATUS_DATA_REQUEST 0x08 +#define IDE_STATUS_CORRECTED_DATA 0x04 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_ERROR 0x01 + +#define IDE_IDENTIFY_COMMAND 0xEC + +#include +#include #include -typedef struct { - uint16_t base, control, busMaster, noInterrupt; -} IdeChannels; - -typedef struct { - IdeChannels *channels; +typedef struct HardDrive { char *model; - uint8_t channel, drive; - uint16_t capabilities, signature, type; - uint32_t commandSets, size; - uint16_t cylinders, heads, sectors; + uint32_t size; + void *interface; + void (*access)(struct HardDrive *, uint32_t, void *, uint8_t, uint8_t); + // todo: mount point } HardDrive; +extern void initializeIDEDrive(PciDevice *, ListElement **); + extern void scanHardDrives(); #endif diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/image.raw b/image.raw deleted file mode 100644 index f120995..0000000 --- a/image.raw +++ /dev/null @@ -1,2 +0,0 @@ -Hello world this is a test image to see if the disk access will work! -If I can see this message everything seems to have worked :) diff --git a/src/include/hardDrive.h b/src/include/hardDrive.h index 819781d..00ada36 100644 --- a/src/include/hardDrive.h +++ b/src/include/hardDrive.h @@ -1,21 +1,44 @@ #ifndef HARD_DRIVE_H #define HARD_DRIVE_H +#define IDE_DATA_REGISTER 0 +#define IDE_ERROR_REGISTER 1 +#define IDE_SECTOR_COUNT_REGISTER 2 +#define IDE_SECTOR_NUMBER_REGISTER 3 +#define IDE_CYLINDER_LOW_REGISTER 4 +#define IDE_CYLINDER_HIGH_REGISTER 5 +// sector size, drive, head +#define IDE_SDH_REGISTER 6 +#define IDE_STATUS_REGISTER 7 +#define IDE_COMMAND_REGISTER 7 +#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 +#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 + +#define IDE_STATUS_BUSY 0x80 +#define IDE_STATUS_READY 0x40 +#define IDE_STATUS_WRITE_FAULT 0x20 +#define IDE_STATUS_SEEK_COMPLETE 0x10 +#define IDE_STATUS_DATA_REQUEST 0x08 +#define IDE_STATUS_CORRECTED_DATA 0x04 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_ERROR 0x01 + +#define IDE_IDENTIFY_COMMAND 0xEC + +#include +#include #include -typedef struct { - uint16_t base, control, busMaster, noInterrupt; -} IdeChannels; - -typedef struct { - IdeChannels *channels; +typedef struct HardDrive { char *model; - uint8_t channel, drive; - uint16_t capabilities, signature, type; - uint32_t commandSets, size; - uint16_t cylinders, heads, sectors; + uint32_t size; + void *interface; + void (*access)(struct HardDrive *, uint32_t, void *, uint8_t, uint8_t); + // todo: mount point } HardDrive; +extern void initializeIDEDrive(PciDevice *, ListElement **); + extern void scanHardDrives(); #endif diff --git a/src/kernel/drivers/pci/hardDrive/ataDrive.c b/src/kernel/drivers/pci/hardDrive/ataDrive.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/kernel/drivers/pci/hardDrive/ataDrive.c diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/image.raw b/image.raw deleted file mode 100644 index f120995..0000000 --- a/image.raw +++ /dev/null @@ -1,2 +0,0 @@ -Hello world this is a test image to see if the disk access will work! -If I can see this message everything seems to have worked :) diff --git a/src/include/hardDrive.h b/src/include/hardDrive.h index 819781d..00ada36 100644 --- a/src/include/hardDrive.h +++ b/src/include/hardDrive.h @@ -1,21 +1,44 @@ #ifndef HARD_DRIVE_H #define HARD_DRIVE_H +#define IDE_DATA_REGISTER 0 +#define IDE_ERROR_REGISTER 1 +#define IDE_SECTOR_COUNT_REGISTER 2 +#define IDE_SECTOR_NUMBER_REGISTER 3 +#define IDE_CYLINDER_LOW_REGISTER 4 +#define IDE_CYLINDER_HIGH_REGISTER 5 +// sector size, drive, head +#define IDE_SDH_REGISTER 6 +#define IDE_STATUS_REGISTER 7 +#define IDE_COMMAND_REGISTER 7 +#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 +#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 + +#define IDE_STATUS_BUSY 0x80 +#define IDE_STATUS_READY 0x40 +#define IDE_STATUS_WRITE_FAULT 0x20 +#define IDE_STATUS_SEEK_COMPLETE 0x10 +#define IDE_STATUS_DATA_REQUEST 0x08 +#define IDE_STATUS_CORRECTED_DATA 0x04 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_ERROR 0x01 + +#define IDE_IDENTIFY_COMMAND 0xEC + +#include +#include #include -typedef struct { - uint16_t base, control, busMaster, noInterrupt; -} IdeChannels; - -typedef struct { - IdeChannels *channels; +typedef struct HardDrive { char *model; - uint8_t channel, drive; - uint16_t capabilities, signature, type; - uint32_t commandSets, size; - uint16_t cylinders, heads, sectors; + uint32_t size; + void *interface; + void (*access)(struct HardDrive *, uint32_t, void *, uint8_t, uint8_t); + // todo: mount point } HardDrive; +extern void initializeIDEDrive(PciDevice *, ListElement **); + extern void scanHardDrives(); #endif diff --git a/src/kernel/drivers/pci/hardDrive/ataDrive.c b/src/kernel/drivers/pci/hardDrive/ataDrive.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/kernel/drivers/pci/hardDrive/ataDrive.c diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index ea36871..3adaea3 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -6,258 +6,6 @@ #include #include -#define IDE_DATA_REGISTER 0 -#define IDE_ERROR_REGISTER 1 -#define IDE_SECTOR_COUNT_REGISTER 2 -#define IDE_SECTOR_NUMBER_REGISTER 3 -#define IDE_CYLINDER_LOW_REGISTER 4 -#define IDE_CYLINDER_HIGH_REGISTER 5 -// sector size, drive, head -#define IDE_SDH_REGISTER 6 -#define IDE_STATUS_REGISTER 7 -#define IDE_COMMAND_REGISTER 7 -#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 -#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 - -#define IDE_STATUS_BUSY 0x80 -#define IDE_STATUS_READY 0x40 -#define IDE_STATUS_WRITE_FAULT 0x20 -#define IDE_STATUS_SEEK_COMPLETE 0x10 -#define IDE_STATUS_DATA_REQUEST 0x08 -#define IDE_STATUS_CORRECTED_DATA 0x04 -#define IDE_STATUS_INDEX 0x02 -#define IDE_STATUS_ERROR 0x01 - -#define IDE_IDENTIFY_COMMAND 0xEC - -char *driveTypes[] = { - "ISA Compatibility mode-only controller", - "PCI native mode-only controller", - "ISA Compatibility mode controller", - "PCI native mode controller", -}; - -void setupIDEChannels(IdeChannels *channels, PciDevice *pciDevice) { - if (pciDevice->programmingInterface & 0x01) { - channels->base = pciDevice->bar0; - channels->control = pciDevice->bar1; - } else { - channels->base = 0x1F0; - channels->control = 0x3F6; - } - if (pciDevice->programmingInterface & 0x04) { - channels[1].base = pciDevice->bar2; - channels[1].control = pciDevice->bar3; - } else { - channels[1].base = 0x170; - channels[1].control = 0x376; - } -} - -void ideWriteControlRegister(IdeChannels *channel, uint8_t reg, uint8_t data) { - outb(channel->control + reg, data); -} - -void ideWriteRegister(IdeChannels *channel, uint8_t reg, uint16_t data) { - outb(channel->base + reg, data); - if (data > 0xFF) { - // set higher half bit in the control register - outb(channel->control, 0x0A); - outb(channel->base + reg, data >> 8); - outb(channel->control, 0x02); - } -} - -uint8_t ideReadControlRegister(IdeChannels *channel, uint8_t reg) { - return inb(channel->control + reg); -} - -uint8_t ideReadRegister(IdeChannels *channel, uint16_t reg) { - return inw(channel->base + reg); -} - -void ideReadBuffer(IdeChannels *channel, uint32_t *data) { - for (uint16_t i = 0; i < 128; i++) { - data[i] = ini(channel->base + IDE_DATA_REGISTER); - } -} - -void printError(uint16_t); - -void ideWaitUntilNotBusy(IdeChannels *channel, bool checkErrors) { - for (uint8_t i = 0; i < 4; i++) { - ideReadControlRegister(channel, 0); - } - uint16_t status = ideReadRegister(channel, IDE_STATUS_REGISTER); - while (status & IDE_STATUS_BUSY) { - status = ideReadRegister(channel, IDE_STATUS_REGISTER); - } - if (checkErrors && status & IDE_STATUS_ERROR) { - printf("encountered an error\n"); - printError(ideReadRegister(channel, IDE_ERROR_REGISTER)); - } -} - -void ideCommand(IdeChannels *channel, uint8_t command) { - ideWaitUntilNotBusy(channel, false); - ideWriteRegister(channel, IDE_COMMAND_REGISTER, command); -} - -#define CHANNEL &channels[channel] - -void initializeIDEDrive(PciDevice *pciDevice, ListElement **drives) { - uint8_t *buffer = malloc(2048); - IdeChannels *channels = malloc(sizeof(IdeChannels) * 2); - setupIDEChannels(channels, pciDevice); - for (uint8_t channel = 0; channel < 2; channel++) { - if (ideReadRegister(CHANNEL, IDE_STATUS_REGISTER) == 0) { - // no device - continue; - } - ideWriteControlRegister(CHANNEL, IDE_ALTERNATE_STATUS_CONTROL_REGISTER, - 2); - for (uint8_t drive = 0; drive < 2; drive++) { - ideWaitUntilNotBusy(CHANNEL, true); - // set the drive - ideWriteRegister(CHANNEL, IDE_SDH_REGISTER, 0xA0 | (drive << 4)); - ideWriteRegister(CHANNEL, IDE_SECTOR_COUNT_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_SECTOR_NUMBER_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_CYLINDER_LOW_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_CYLINDER_HIGH_REGISTER, 0); - ideCommand(CHANNEL, IDE_IDENTIFY_COMMAND); - ideWaitUntilNotBusy(CHANNEL, true); - ideReadBuffer(CHANNEL, (void *)buffer); - if (*((uint16_t *)buffer) == 0) { - // any bit has to be set if it is a real device - continue; - } - char *model = malloc(41); - for (int i = 0; i < 40; i += 2) { - *((uint16_t *)&model[i]) = buffer[54 + i + 1]; - *((uint16_t *)&model[i + 1]) = buffer[54 + i]; - } - model[40] = 0; - HardDrive *hardDrive = malloc(sizeof(HardDrive)); - hardDrive->model = model; - hardDrive->channels = CHANNEL; - hardDrive->channel = channel; - hardDrive->drive = drive; - hardDrive->type = *(uint16_t *)buffer; - hardDrive->cylinders = *(uint16_t *)buffer + 2; - hardDrive->heads = *(uint16_t *)buffer + 6; - hardDrive->sectors = *(uint16_t *)buffer + 12; - hardDrive->capabilities = *(uint16_t *)buffer + 98; - hardDrive->commandSets = *(uint32_t *)(buffer + 164); - if (hardDrive->commandSets + (1 << 26)) { - hardDrive->size = *(uint32_t *)buffer + 200; - } else { - hardDrive->size = *(uint32_t *)buffer + 120; - } - listAdd(drives, hardDrive); - printf("found a hard drive %i bytes, %i:%i, model: %s\n", - hardDrive->size, channel, drive, model); - } - } - free(buffer); -} - -void printError(uint16_t status) { - if (status & 0x01) { - printf("No address mark\n"); - } - if (status & 0x02) { - printf("Track 0 not found\n"); - } - if (status & 0x04) { - printf("command aborted\n"); - } - if (status & 0x08) { - printf("Media change request\n"); - } - if (status & 0x10) { - printf("ID mark not found\n"); - } - if (status & 0x20) { - printf("Media changed\n"); - } - if (status & 0x40) { - printf("uncorrectable data\n"); - } - if (status & 0x80) { - printf("bad block\n"); - } -} - -void driveAccess(HardDrive *hardDrive, uint32_t lba, void *buffer, - uint8_t sectorCount, uint8_t direction) { - uint8_t accessMode = 0, head = 0, sector = 0, cylinder = 0; - uint32_t lbaIo[6] = {0, 0, 0, 0, 0, 0}; - if (lba >= 0x10000000) { - accessMode = 2; - lbaIo[0] = (uint8_t)lba; - lbaIo[1] = (lba & 0x0000FF00) >> 8; - lbaIo[2] = (lba & 0x00FF0000) >> 16; - lbaIo[3] = (lba & 0xFF000000) >> 24; - } else if (hardDrive->capabilities & 0x200) { - accessMode = 1; - lbaIo[0] = (uint8_t)lba; - lbaIo[1] = (lba & 0x000FF00) >> 8; - lbaIo[2] = (lba & 0x0FF0000) >> 16; - head = (lba & 0xF000000) >> 24; - } else { - sector = (lba % 63) + 1; - cylinder = (lba + 1 - sector) / (16 * 63); - lbaIo[0] = sector; - lbaIo[1] = (uint8_t)cylinder; - lbaIo[2] = (cylinder >> 8) & 0xFF; - head = (lba + 1 - sector) % (16 * 63) / (63); - } - ideWaitUntilNotBusy(hardDrive->channels, true); - if (accessMode == 0) { - // chs - ideWriteRegister(hardDrive->channels, IDE_SDH_REGISTER, - 0xA0 | (hardDrive->drive << 4)); - } else { - // lba - ideWriteRegister(hardDrive->channels, IDE_SDH_REGISTER, - 0xE0 | (hardDrive->drive << 4) | head); - } - ideWriteRegister(hardDrive->channels, IDE_SECTOR_COUNT_REGISTER, - sectorCount); - ideWriteRegister(hardDrive->channels, IDE_SECTOR_NUMBER_REGISTER, - lbaIo[3] << 8 | lbaIo[0]); - ideWriteRegister(hardDrive->channels, IDE_CYLINDER_LOW_REGISTER, - lbaIo[4] << 8 | lbaIo[1]); - ideWriteRegister(hardDrive->channels, IDE_CYLINDER_HIGH_REGISTER, - lbaIo[5] << 8 | lbaIo[2]); - uint8_t command = 0; - if (direction == 0) { - // read - if (accessMode == 2) { - command = 0x24; - } else { - command = 0x20; - } - } else { - // write - if (accessMode == 2) { - command = 0x34; - } else { - command = 0x30; - } - } - ideCommand(hardDrive->channels, command); - ideWaitUntilNotBusy(hardDrive->channels, true); - if (direction == 0) { - uint16_t status; - void *current = buffer; - for (uint8_t i = 0; i < sectorCount; i++) { - ideWaitUntilNotBusy(hardDrive->channels, true); - ideReadBuffer(hardDrive->channels, (void *)buffer); - } - } -} - void initializeSATADrive(PciDevice *pciDevice) { // todo } @@ -283,7 +31,8 @@ } void *buffer = malloc(2000); for (ListElement *current = drives; current; current = current->next) { - driveAccess(current->data, 0, buffer, 1, 0); + HardDrive *hardDrive = current->data; + hardDrive->access(hardDrive, 0, buffer, 1, 0); printf("data: %x %x %s\n", *(uint32_t *)buffer, *((uint32_t *)buffer + 1), buffer); } diff --git a/.gitignore b/.gitignore index 84c2767..dba3c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ tree-os.iso build iso/boot/tree-os.bin -.vscode \ No newline at end of file +.vscode +disk.img diff --git a/Makefile b/Makefile index 96dac6b..3a9dada 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = i686-elf-gcc -CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers +CCFLAGS = -m32 -mtune=generic -ffreestanding -nostdlib -c -I src/include -Wno-discarded-qualifiers -fms-extensions LD = i686-elf-ld LD_FLAGS = -z max-page-size=0x1000 -T linker.ld AS = nasm @@ -7,7 +7,7 @@ GENISO = genisoimage GENISOFLAGS = -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -input-charset utf8 -quiet -boot-info-table -A tree-os EMU = qemu-system-x86_64 -EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=image.raw +EMUFLAGS = -m 256M -drive format=raw,file=tree-os.iso -drive format=raw,file=disk.img BUILD_FOLDER = build diff --git a/compile_flags.txt b/compile_flags.txt index 4a197fa..73386c5 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,2 +1,3 @@ clang -I./src/include +-fms-extensions diff --git a/image.raw b/image.raw deleted file mode 100644 index f120995..0000000 --- a/image.raw +++ /dev/null @@ -1,2 +0,0 @@ -Hello world this is a test image to see if the disk access will work! -If I can see this message everything seems to have worked :) diff --git a/src/include/hardDrive.h b/src/include/hardDrive.h index 819781d..00ada36 100644 --- a/src/include/hardDrive.h +++ b/src/include/hardDrive.h @@ -1,21 +1,44 @@ #ifndef HARD_DRIVE_H #define HARD_DRIVE_H +#define IDE_DATA_REGISTER 0 +#define IDE_ERROR_REGISTER 1 +#define IDE_SECTOR_COUNT_REGISTER 2 +#define IDE_SECTOR_NUMBER_REGISTER 3 +#define IDE_CYLINDER_LOW_REGISTER 4 +#define IDE_CYLINDER_HIGH_REGISTER 5 +// sector size, drive, head +#define IDE_SDH_REGISTER 6 +#define IDE_STATUS_REGISTER 7 +#define IDE_COMMAND_REGISTER 7 +#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 +#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 + +#define IDE_STATUS_BUSY 0x80 +#define IDE_STATUS_READY 0x40 +#define IDE_STATUS_WRITE_FAULT 0x20 +#define IDE_STATUS_SEEK_COMPLETE 0x10 +#define IDE_STATUS_DATA_REQUEST 0x08 +#define IDE_STATUS_CORRECTED_DATA 0x04 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_ERROR 0x01 + +#define IDE_IDENTIFY_COMMAND 0xEC + +#include +#include #include -typedef struct { - uint16_t base, control, busMaster, noInterrupt; -} IdeChannels; - -typedef struct { - IdeChannels *channels; +typedef struct HardDrive { char *model; - uint8_t channel, drive; - uint16_t capabilities, signature, type; - uint32_t commandSets, size; - uint16_t cylinders, heads, sectors; + uint32_t size; + void *interface; + void (*access)(struct HardDrive *, uint32_t, void *, uint8_t, uint8_t); + // todo: mount point } HardDrive; +extern void initializeIDEDrive(PciDevice *, ListElement **); + extern void scanHardDrives(); #endif diff --git a/src/kernel/drivers/pci/hardDrive/ataDrive.c b/src/kernel/drivers/pci/hardDrive/ataDrive.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/kernel/drivers/pci/hardDrive/ataDrive.c diff --git a/src/kernel/drivers/pci/hardDrive/hardDrive.c b/src/kernel/drivers/pci/hardDrive/hardDrive.c index ea36871..3adaea3 100644 --- a/src/kernel/drivers/pci/hardDrive/hardDrive.c +++ b/src/kernel/drivers/pci/hardDrive/hardDrive.c @@ -6,258 +6,6 @@ #include #include -#define IDE_DATA_REGISTER 0 -#define IDE_ERROR_REGISTER 1 -#define IDE_SECTOR_COUNT_REGISTER 2 -#define IDE_SECTOR_NUMBER_REGISTER 3 -#define IDE_CYLINDER_LOW_REGISTER 4 -#define IDE_CYLINDER_HIGH_REGISTER 5 -// sector size, drive, head -#define IDE_SDH_REGISTER 6 -#define IDE_STATUS_REGISTER 7 -#define IDE_COMMAND_REGISTER 7 -#define IDE_ALTERNATE_STATUS_CONTROL_REGISTER 0 -#define IDE_DRIVE_ADDRESS_CONTROL_REGISTER 1 - -#define IDE_STATUS_BUSY 0x80 -#define IDE_STATUS_READY 0x40 -#define IDE_STATUS_WRITE_FAULT 0x20 -#define IDE_STATUS_SEEK_COMPLETE 0x10 -#define IDE_STATUS_DATA_REQUEST 0x08 -#define IDE_STATUS_CORRECTED_DATA 0x04 -#define IDE_STATUS_INDEX 0x02 -#define IDE_STATUS_ERROR 0x01 - -#define IDE_IDENTIFY_COMMAND 0xEC - -char *driveTypes[] = { - "ISA Compatibility mode-only controller", - "PCI native mode-only controller", - "ISA Compatibility mode controller", - "PCI native mode controller", -}; - -void setupIDEChannels(IdeChannels *channels, PciDevice *pciDevice) { - if (pciDevice->programmingInterface & 0x01) { - channels->base = pciDevice->bar0; - channels->control = pciDevice->bar1; - } else { - channels->base = 0x1F0; - channels->control = 0x3F6; - } - if (pciDevice->programmingInterface & 0x04) { - channels[1].base = pciDevice->bar2; - channels[1].control = pciDevice->bar3; - } else { - channels[1].base = 0x170; - channels[1].control = 0x376; - } -} - -void ideWriteControlRegister(IdeChannels *channel, uint8_t reg, uint8_t data) { - outb(channel->control + reg, data); -} - -void ideWriteRegister(IdeChannels *channel, uint8_t reg, uint16_t data) { - outb(channel->base + reg, data); - if (data > 0xFF) { - // set higher half bit in the control register - outb(channel->control, 0x0A); - outb(channel->base + reg, data >> 8); - outb(channel->control, 0x02); - } -} - -uint8_t ideReadControlRegister(IdeChannels *channel, uint8_t reg) { - return inb(channel->control + reg); -} - -uint8_t ideReadRegister(IdeChannels *channel, uint16_t reg) { - return inw(channel->base + reg); -} - -void ideReadBuffer(IdeChannels *channel, uint32_t *data) { - for (uint16_t i = 0; i < 128; i++) { - data[i] = ini(channel->base + IDE_DATA_REGISTER); - } -} - -void printError(uint16_t); - -void ideWaitUntilNotBusy(IdeChannels *channel, bool checkErrors) { - for (uint8_t i = 0; i < 4; i++) { - ideReadControlRegister(channel, 0); - } - uint16_t status = ideReadRegister(channel, IDE_STATUS_REGISTER); - while (status & IDE_STATUS_BUSY) { - status = ideReadRegister(channel, IDE_STATUS_REGISTER); - } - if (checkErrors && status & IDE_STATUS_ERROR) { - printf("encountered an error\n"); - printError(ideReadRegister(channel, IDE_ERROR_REGISTER)); - } -} - -void ideCommand(IdeChannels *channel, uint8_t command) { - ideWaitUntilNotBusy(channel, false); - ideWriteRegister(channel, IDE_COMMAND_REGISTER, command); -} - -#define CHANNEL &channels[channel] - -void initializeIDEDrive(PciDevice *pciDevice, ListElement **drives) { - uint8_t *buffer = malloc(2048); - IdeChannels *channels = malloc(sizeof(IdeChannels) * 2); - setupIDEChannels(channels, pciDevice); - for (uint8_t channel = 0; channel < 2; channel++) { - if (ideReadRegister(CHANNEL, IDE_STATUS_REGISTER) == 0) { - // no device - continue; - } - ideWriteControlRegister(CHANNEL, IDE_ALTERNATE_STATUS_CONTROL_REGISTER, - 2); - for (uint8_t drive = 0; drive < 2; drive++) { - ideWaitUntilNotBusy(CHANNEL, true); - // set the drive - ideWriteRegister(CHANNEL, IDE_SDH_REGISTER, 0xA0 | (drive << 4)); - ideWriteRegister(CHANNEL, IDE_SECTOR_COUNT_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_SECTOR_NUMBER_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_CYLINDER_LOW_REGISTER, 0); - ideWriteRegister(CHANNEL, IDE_CYLINDER_HIGH_REGISTER, 0); - ideCommand(CHANNEL, IDE_IDENTIFY_COMMAND); - ideWaitUntilNotBusy(CHANNEL, true); - ideReadBuffer(CHANNEL, (void *)buffer); - if (*((uint16_t *)buffer) == 0) { - // any bit has to be set if it is a real device - continue; - } - char *model = malloc(41); - for (int i = 0; i < 40; i += 2) { - *((uint16_t *)&model[i]) = buffer[54 + i + 1]; - *((uint16_t *)&model[i + 1]) = buffer[54 + i]; - } - model[40] = 0; - HardDrive *hardDrive = malloc(sizeof(HardDrive)); - hardDrive->model = model; - hardDrive->channels = CHANNEL; - hardDrive->channel = channel; - hardDrive->drive = drive; - hardDrive->type = *(uint16_t *)buffer; - hardDrive->cylinders = *(uint16_t *)buffer + 2; - hardDrive->heads = *(uint16_t *)buffer + 6; - hardDrive->sectors = *(uint16_t *)buffer + 12; - hardDrive->capabilities = *(uint16_t *)buffer + 98; - hardDrive->commandSets = *(uint32_t *)(buffer + 164); - if (hardDrive->commandSets + (1 << 26)) { - hardDrive->size = *(uint32_t *)buffer + 200; - } else { - hardDrive->size = *(uint32_t *)buffer + 120; - } - listAdd(drives, hardDrive); - printf("found a hard drive %i bytes, %i:%i, model: %s\n", - hardDrive->size, channel, drive, model); - } - } - free(buffer); -} - -void printError(uint16_t status) { - if (status & 0x01) { - printf("No address mark\n"); - } - if (status & 0x02) { - printf("Track 0 not found\n"); - } - if (status & 0x04) { - printf("command aborted\n"); - } - if (status & 0x08) { - printf("Media change request\n"); - } - if (status & 0x10) { - printf("ID mark not found\n"); - } - if (status & 0x20) { - printf("Media changed\n"); - } - if (status & 0x40) { - printf("uncorrectable data\n"); - } - if (status & 0x80) { - printf("bad block\n"); - } -} - -void driveAccess(HardDrive *hardDrive, uint32_t lba, void *buffer, - uint8_t sectorCount, uint8_t direction) { - uint8_t accessMode = 0, head = 0, sector = 0, cylinder = 0; - uint32_t lbaIo[6] = {0, 0, 0, 0, 0, 0}; - if (lba >= 0x10000000) { - accessMode = 2; - lbaIo[0] = (uint8_t)lba; - lbaIo[1] = (lba & 0x0000FF00) >> 8; - lbaIo[2] = (lba & 0x00FF0000) >> 16; - lbaIo[3] = (lba & 0xFF000000) >> 24; - } else if (hardDrive->capabilities & 0x200) { - accessMode = 1; - lbaIo[0] = (uint8_t)lba; - lbaIo[1] = (lba & 0x000FF00) >> 8; - lbaIo[2] = (lba & 0x0FF0000) >> 16; - head = (lba & 0xF000000) >> 24; - } else { - sector = (lba % 63) + 1; - cylinder = (lba + 1 - sector) / (16 * 63); - lbaIo[0] = sector; - lbaIo[1] = (uint8_t)cylinder; - lbaIo[2] = (cylinder >> 8) & 0xFF; - head = (lba + 1 - sector) % (16 * 63) / (63); - } - ideWaitUntilNotBusy(hardDrive->channels, true); - if (accessMode == 0) { - // chs - ideWriteRegister(hardDrive->channels, IDE_SDH_REGISTER, - 0xA0 | (hardDrive->drive << 4)); - } else { - // lba - ideWriteRegister(hardDrive->channels, IDE_SDH_REGISTER, - 0xE0 | (hardDrive->drive << 4) | head); - } - ideWriteRegister(hardDrive->channels, IDE_SECTOR_COUNT_REGISTER, - sectorCount); - ideWriteRegister(hardDrive->channels, IDE_SECTOR_NUMBER_REGISTER, - lbaIo[3] << 8 | lbaIo[0]); - ideWriteRegister(hardDrive->channels, IDE_CYLINDER_LOW_REGISTER, - lbaIo[4] << 8 | lbaIo[1]); - ideWriteRegister(hardDrive->channels, IDE_CYLINDER_HIGH_REGISTER, - lbaIo[5] << 8 | lbaIo[2]); - uint8_t command = 0; - if (direction == 0) { - // read - if (accessMode == 2) { - command = 0x24; - } else { - command = 0x20; - } - } else { - // write - if (accessMode == 2) { - command = 0x34; - } else { - command = 0x30; - } - } - ideCommand(hardDrive->channels, command); - ideWaitUntilNotBusy(hardDrive->channels, true); - if (direction == 0) { - uint16_t status; - void *current = buffer; - for (uint8_t i = 0; i < sectorCount; i++) { - ideWaitUntilNotBusy(hardDrive->channels, true); - ideReadBuffer(hardDrive->channels, (void *)buffer); - } - } -} - void initializeSATADrive(PciDevice *pciDevice) { // todo } @@ -283,7 +31,8 @@ } void *buffer = malloc(2000); for (ListElement *current = drives; current; current = current->next) { - driveAccess(current->data, 0, buffer, 1, 0); + HardDrive *hardDrive = current->data; + hardDrive->access(hardDrive, 0, buffer, 1, 0); printf("data: %x %x %s\n", *(uint32_t *)buffer, *((uint32_t *)buffer + 1), buffer); } diff --git a/src/kernel/drivers/pci/hardDrive/ideController.c b/src/kernel/drivers/pci/hardDrive/ideController.c new file mode 100644 index 0000000..ef3ea00 --- /dev/null +++ b/src/kernel/drivers/pci/hardDrive/ideController.c @@ -0,0 +1,247 @@ +#include <_stdio.h> +#include +#include +#include + +typedef struct { + uint16_t base, control, busMaster; +} IdeChannels; + +typedef struct { + IdeChannels *channels; + uint8_t channel, drive, cylinders, heads, sectors; + uint16_t capabilities, signature, type; + uint32_t commandSets; +} IdeInterface; + +void ideWriteControlRegister(IdeChannels *channel, uint8_t reg, uint8_t data) { + outb(channel->control + reg, data); +} + +void ideWriteRegister(IdeChannels *channel, uint8_t reg, uint16_t data) { + outb(channel->base + reg, data); + if (data > 0xFF) { + // set higher half bit in the control register + outb(channel->control, 0x0A); + outb(channel->base + reg, data >> 8); + outb(channel->control, 0x02); + } +} + +uint8_t ideReadControlRegister(IdeChannels *channel, uint8_t reg) { + return inb(channel->control + reg); +} + +uint8_t ideReadRegister(IdeChannels *channel, uint16_t reg) { + return inw(channel->base + reg); +} + +void ideReadBuffer(IdeChannels *channel, uint32_t *data) { + for (uint16_t i = 0; i < 128; i++) { + data[i] = ini(channel->base + IDE_DATA_REGISTER); + } +} + +void printError(uint16_t status) { + if (status & 0x01) { + printf("No address mark\n"); + } + if (status & 0x02) { + printf("Track 0 not found\n"); + } + if (status & 0x04) { + printf("command aborted\n"); + } + if (status & 0x08) { + printf("Media change request\n"); + } + if (status & 0x10) { + printf("ID mark not found\n"); + } + if (status & 0x20) { + printf("Media changed\n"); + } + if (status & 0x40) { + printf("uncorrectable data\n"); + } + if (status & 0x80) { + printf("bad block\n"); + } +} + +void ideWaitUntilNotBusy(IdeChannels *channel, bool checkErrors) { + for (uint8_t i = 0; i < 4; i++) { + ideReadControlRegister(channel, 0); + } + uint16_t status = ideReadRegister(channel, IDE_STATUS_REGISTER); + while (status & IDE_STATUS_BUSY) { + status = ideReadRegister(channel, IDE_STATUS_REGISTER); + } + if (checkErrors && status & IDE_STATUS_ERROR) { + printf("encountered an error\n"); + printError(ideReadRegister(channel, IDE_ERROR_REGISTER)); + } +} + +void ideCommand(IdeChannels *channel, uint8_t command) { + ideWaitUntilNotBusy(channel, false); + ideWriteRegister(channel, IDE_COMMAND_REGISTER, command); +} + +#define CHANNEL channels[channel] + +void ideDriveAccess(HardDrive *hardDrive, uint32_t lba, void *buffer, + uint8_t sectorCount, uint8_t direction) { + uint8_t accessMode = 0, head = 0, sector = 0, cylinder = 0; + uint32_t lbaIo[6] = {0, 0, 0, 0, 0, 0}; + IdeInterface *interface = hardDrive->interface; + if (lba >= 0x10000000) { + accessMode = 2; + lbaIo[0] = (uint8_t)lba; + lbaIo[1] = (lba & 0x0000FF00) >> 8; + lbaIo[2] = (lba & 0x00FF0000) >> 16; + lbaIo[3] = (lba & 0xFF000000) >> 24; + } else if (interface->capabilities & 0x200) { + accessMode = 1; + lbaIo[0] = (uint8_t)lba; + lbaIo[1] = (lba & 0x000FF00) >> 8; + lbaIo[2] = (lba & 0x0FF0000) >> 16; + head = (lba & 0xF000000) >> 24; + } else { + sector = (lba % 63) + 1; + cylinder = (lba + 1 - sector) / (16 * 63); + lbaIo[0] = sector; + lbaIo[1] = (uint8_t)cylinder; + lbaIo[2] = (cylinder >> 8) & 0xFF; + head = (lba + 1 - sector) % (16 * 63) / (63); + } + ideWaitUntilNotBusy(interface->channels, true); + if (accessMode == 0) { + // chs + ideWriteRegister(interface->channels, IDE_SDH_REGISTER, + 0xA0 | (interface->drive << 4)); + } else { + // lba + ideWriteRegister(interface->channels, IDE_SDH_REGISTER, + 0xE0 | (interface->drive << 4) | head); + } + ideWriteRegister(interface->channels, IDE_SECTOR_COUNT_REGISTER, + sectorCount); + ideWriteRegister(interface->channels, IDE_SECTOR_NUMBER_REGISTER, + lbaIo[3] << 8 | lbaIo[0]); + ideWriteRegister(interface->channels, IDE_CYLINDER_LOW_REGISTER, + lbaIo[4] << 8 | lbaIo[1]); + ideWriteRegister(interface->channels, IDE_CYLINDER_HIGH_REGISTER, + lbaIo[5] << 8 | lbaIo[2]); + uint8_t command = 0; + if (direction == 0) { + // read + if (accessMode == 2) { + command = 0x24; + } else { + command = 0x20; + } + } else { + // write + if (accessMode == 2) { + command = 0x34; + } else { + command = 0x30; + } + } + ideCommand(interface->channels, command); + ideWaitUntilNotBusy(interface->channels, true); + if (direction == 0) { + uint16_t status; + void *current = buffer; + for (uint8_t i = 0; i < sectorCount; i++) { + ideWaitUntilNotBusy(interface->channels, true); + ideReadBuffer(interface->channels, (void *)buffer + 256 * i); + } + } +} + +void setupIDEChannels(IdeChannels **channels, PciDevice *pciDevice) { + if (pciDevice->programmingInterface & 0x01) { + channels[0]->base = pciDevice->bar0; + channels[0]->control = pciDevice->bar1; + } else { + channels[0]->base = 0x1F0; + channels[0]->control = 0x3F6; + } + if (pciDevice->programmingInterface & 0x04) { + channels[1]->base = pciDevice->bar2; + channels[1]->control = pciDevice->bar3; + } else { + channels[1]->base = 0x170; + channels[1]->control = 0x376; + } +} + +void initializeIDEDrive(PciDevice *pciDevice, ListElement **drives) { + uint8_t *buffer = malloc(2048); + IdeChannels *channels[] = {malloc(sizeof(IdeChannels)), + malloc(sizeof(IdeChannels))}; + uint8_t usedChannels = 0; // to be able to clean up later + setupIDEChannels(channels, pciDevice); + for (uint8_t channel = 0; channel < 2; channel++) { + if (ideReadRegister(CHANNEL, IDE_STATUS_REGISTER) == 0) { + // no device + continue; + } + ideWriteControlRegister(CHANNEL, IDE_ALTERNATE_STATUS_CONTROL_REGISTER, + 2); + for (uint8_t drive = 0; drive < 2; drive++) { + ideWaitUntilNotBusy(CHANNEL, true); + // set the drive + ideWriteRegister(CHANNEL, IDE_SDH_REGISTER, 0xA0 | (drive << 4)); + ideWriteRegister(CHANNEL, IDE_SECTOR_COUNT_REGISTER, 0); + ideWriteRegister(CHANNEL, IDE_SECTOR_NUMBER_REGISTER, 0); + ideWriteRegister(CHANNEL, IDE_CYLINDER_LOW_REGISTER, 0); + ideWriteRegister(CHANNEL, IDE_CYLINDER_HIGH_REGISTER, 0); + ideCommand(CHANNEL, IDE_IDENTIFY_COMMAND); + ideWaitUntilNotBusy(CHANNEL, true); + ideReadBuffer(CHANNEL, (void *)buffer); + if (*((uint16_t *)buffer) == 0) { + // any bit has to be set if it is a real device + continue; + } + char *model = malloc(41); + for (int i = 0; i < 40; i += 2) { + *((uint16_t *)&model[i]) = buffer[54 + i + 1]; + *((uint16_t *)&model[i + 1]) = buffer[54 + i]; + } + model[40] = 0; + usedChannels |= 1 << channel; + HardDrive *hardDrive = malloc(sizeof(HardDrive)); + IdeInterface *interface = malloc(sizeof(IdeInterface)); + hardDrive->interface = interface; + hardDrive->model = model; + hardDrive->access = ideDriveAccess; + interface->channels = CHANNEL; + interface->channel = channel; + interface->drive = drive; + interface->type = *(uint16_t *)buffer; + interface->cylinders = *(uint16_t *)buffer + 2; + interface->heads = *(uint16_t *)buffer + 6; + interface->sectors = *(uint16_t *)buffer + 12; + interface->capabilities = *(uint16_t *)buffer + 98; + interface->commandSets = *(uint32_t *)(buffer + 164); + if (interface->commandSets + (1 << 26)) { + hardDrive->size = *(uint32_t *)buffer + 200; + } else { + hardDrive->size = *(uint32_t *)buffer + 120; + } + listAdd(drives, hardDrive); + printf("found a hard drive %i sectors big, model: %s\n", + hardDrive->size, model); + } + } + if (!(usedChannels & 1)) { + free(channels[0]); + } + if (!(usedChannels & 2)) { + free(channels[1]); + } + free(buffer); +}