lol i got it to read and write

This commit is contained in:
hippoz 2020-12-16 12:59:52 +02:00
parent 692a4ff7b8
commit c5cecbb450
Signed by untrusted user who does not match committer: hippoz
GPG key ID: 7C52899193467641
4 changed files with 86 additions and 71 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
*.o
*.bin
*.iso
disk.img

View file

@ -28,7 +28,7 @@ dirs:
all: dirs $(BIN)
run: $(ISO)
$(QEMU) -cdrom $(ISO)
$(QEMU) -cdrom $(ISO) -drive id=disk,file=build/disk.img,if=none,format=raw -device ide-hd,drive=disk,bus=ide.0
$(ISO): dirs $(BIN)
grub-mkrescue -o $(ISO) sysroot

View file

@ -308,7 +308,7 @@ void ide_wait_irq() {
ide_irq_invoked = 0;
}
unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsigned int lba, unsigned char numsects, unsigned short selector, unsigned int edi) {
unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsigned int lba, uint8_t* buf) {
unsigned char lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */, dma /* 0: No DMA, 1: DMA */, cmd;
unsigned char lba_io[6];
unsigned int channel = ide_devices[drive].Channel; // Read the Channel.
@ -376,7 +376,7 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsig
ide_write(channel, ATA_REG_LBA4, lba_io[4]);
ide_write(channel, ATA_REG_LBA5, lba_io[5]);
}
ide_write(channel, ATA_REG_SECCOUNT0, numsects);
ide_write(channel, ATA_REG_SECCOUNT0, 1); // Number of sectors, always 1 in our case
ide_write(channel, ATA_REG_LBA0, lba_io[0]);
ide_write(channel, ATA_REG_LBA1, lba_io[1]);
ide_write(channel, ATA_REG_LBA2, lba_io[2]);
@ -410,30 +410,24 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsig
else;
// DMA Write.
else
if (direction == 0)
if (direction == 0) {
// PIO Read.
for (i = 0; i < numsects; i++) {
if (err = ide_polling(channel, 1))
return err; // Polling, set error and exit if there is.
asm("pushw %es");
asm("mov %%ax, %%es" : : "a"(selector));
asm("rep insw" : : "c"(words), "d"(bus), "D"(edi)); // Receive Data.
asm("popw %es");
edi += (words*2);
if (err = ide_polling(channel, 1)) return err; // Polling, set error and exit if there is.
inportsm(bus, buf, words);
ide_write(channel, ATA_REG_COMMAND, (char []) { (char)ATA_CMD_CACHE_FLUSH,
(char)ATA_CMD_CACHE_FLUSH,
(char)ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);
ide_polling(channel, 0); // Polling.
} else {
// PIO Write.
for (i = 0; i < numsects; i++) {
ide_polling(channel, 0); // Polling.
asm("pushw %ds");
asm("mov %%ax, %%ds"::"a"(selector));
asm("rep outsw"::"c"(words), "d"(bus), "S"(edi)); // Send Data
asm("popw %ds");
edi += (words*2);
}
ide_write(channel, ATA_REG_COMMAND, (char []) { ATA_CMD_CACHE_FLUSH,
ATA_CMD_CACHE_FLUSH,
ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);
// PIO Write.
ide_polling(channel, 0); // Polling.
outportsm(bus, buf, words);
ide_write(channel, ATA_REG_COMMAND, (char []) { ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH_EXT }[lba_mode]);
ide_polling(channel, 0);
}
return 0; // Easy, isn't it? no
@ -520,53 +514,41 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba, unsigned cha
return 0; // Easy, ... Isn't it? no
}
void ide_read_sectors(unsigned char drive, unsigned char numsects, unsigned int lba,
unsigned short es, unsigned int edi, unsigned char* package) {
uint8_t ide_read_sectors(unsigned char drive, unsigned int lba, uint8_t* buf) {
// 1: Check if the drive presents:
// ==================================
if (drive > 3 || ide_devices[drive].Reserved == 0) package[0] = 0x1; // Drive Not Found!
// 2: Check if inputs are valid:
// ==================================
else if (((lba + numsects) > ide_devices[drive].Size) && (ide_devices[drive].Type == IDE_ATA))
package[0] = 0x2; // Seeking to invalid position.
// 3: Read in PIO Mode through Polling & IRQs:
// ============================================
else {
unsigned char err;
if (ide_devices[drive].Type == IDE_ATA)
err = ide_ata_access(ATA_READ, drive, lba, numsects, es, edi);
else if (ide_devices[drive].Type == IDE_ATAPI)
for (int i = 0; i < numsects; i++)
err = ide_atapi_read(drive, lba + i, 1, es, edi + (i*2048));
package[0] = ide_print_error(drive, err);
}
}
// package[0] is an entry of an array. It contains the Error Code.
// Check if the drive is present:
if (drive > 3 || ide_devices[drive].Reserved == 0) return 0x01; // Drive not present
void ide_write_sectors(unsigned char drive, unsigned char numsects, unsigned int lba,
unsigned short es, unsigned int edi, unsigned char* package) {
// 1: Check if the drive presents:
// ==================================
if (drive > 3 || ide_devices[drive].Reserved == 0)
package[0] = 0x1; // Drive Not Found!
// 2: Check if inputs are valid:
// ==================================
else if (((lba + numsects) > ide_devices[drive].Size) && (ide_devices[drive].Type == IDE_ATA))
package[0] = 0x2; // Seeking to invalid position.
// 3: Read in PIO Mode through Polling & IRQs:
// ============================================
else {
unsigned char err;
if (ide_devices[drive].Type == IDE_ATA)
err = ide_ata_access(ATA_WRITE, drive, lba, numsects, es, edi);
else if (ide_devices[drive].Type == IDE_ATAPI)
err = 4; // Write-Protected.
package[0] = ide_print_error(drive, err);
// Check if inputs are valid:
if (((lba + 1) > ide_devices[drive].Size) && (ide_devices[drive].Type == IDE_ATA)) return 0x02; // Seeking to invalid position.
// Read in PIO Mode through Polling & IRQs:
unsigned char err;
if (ide_devices[drive].Type == IDE_ATA) {
err = ide_ata_access(ATA_READ, drive, lba, buf);
} else {
// err = ide_atapi_read(drive, lba + i, 1, es, edi + (i*2048));
return 0x03; // We don't support this yet.
}
return ide_print_error(drive, err);
}
uint8_t ide_write_sectors(unsigned char drive, unsigned int lba, uint8_t* buf) {
// Check if the drive is present:
if (drive > 3 || ide_devices[drive].Reserved == 0) return 0x01; // Drive not present
// Check if inputs are valid:
if (((lba + 1) > ide_devices[drive].Size) && (ide_devices[drive].Type == IDE_ATA)) return 0x02; // Seeking to invalid position.
// Write in PIO Mode through Polling & IRQs:
unsigned char err;
if (ide_devices[drive].Type == IDE_ATA) {
err = ide_ata_access(ATA_WRITE, drive, lba, buf);
} else {
err = 4; // Write-Protected.
}
return ide_print_error(drive, err);
}
void ide_atapi_eject(unsigned char drive, unsigned char* package) {
@ -640,7 +622,30 @@ void ide_atapi_eject(unsigned char drive, unsigned char* package) {
}
void ide_init() {
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
sleep(1);
ide_write_sectors(0, )
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
sleep(1);
uint8_t buf[512] = {
69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
};
ide_write_sectors(0, 1, buf);
sleep(1);
sleep(1);
sleep(1);
uint8_t outbuf[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
ide_read_sectors(0, 1, outbuf);
sleep(1);
sleep(1);
sleep(1);
for (uint8_t i = 0; i < 3; i++) {
terminal_writestring(itoa(i));
terminal_writeline(itoa(outbuf[i]));
}
}

View file

@ -50,6 +50,15 @@ static inline bool are_interrupts_enabled() {
return flags & (1 << 9);
}
inline static void inportsm(unsigned short port, unsigned char* data, unsigned long size)
{
asm volatile ("rep insw" : "+D" (data), "+c" (size) : "d" (port) : "memory");
}
inline static void outportsm(unsigned short port, unsigned char* data, unsigned long size) {
asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port));
}
static void insl(unsigned reg, unsigned int *buffer, int quads)
{
int index;