📄 ide_raw.c
字号:
block /= device->hardware_device.heads; *cylinder = block & 0xFFFF; dprintf("ata_block_to_chs(): block %d -> cyl %d head %d sect %d\n", block, *cylinder, *head, *sect);}static void ata_block_to_lba(uint32 block, ide_device *device, int *cylinder, int *head, int *sect){ *sect = block & 0xFF; *cylinder = (block >> 8) & 0xFFFF; *head = ((block >> 24) & 0xF) | CB_DH_LBA; dprintf("ata_block_to_lba(): block %d -> cyl %d head %d sect %d\n", block, *cylinder, *head, *sect);}int ata_read_sector(ide_device *device, char *data, uint32 sector, uint16 numSectors){ int cyl, head, sect; dprintf("ata_read_sector: dev %p, data %p, block 0x%x, sectors 0x%x\n", device, data, sector, numSectors); if(device->lba_supported) ata_block_to_lba(sector, device, &cyl, &head, §); else ata_block_to_chs(sector, device, &cyl, &head, §); return reg_pio_data_in(device->bus, device->device, CMD_READ_SECTORS, 0, numSectors, cyl, head, sect, data, numSectors, 2);}int ata_write_sector(ide_device *device, const char *data, uint32 sector, uint16 numSectors){ int cyl, head, sect; dprintf("ata_write_sector: dev %p, data %p, block 0x%x, sectors 0x%x\n", device, data, sector, numSectors); if(device->lba_supported) ata_block_to_lba(sector, device, &cyl, &head, §); else ata_block_to_chs(sector, device, &cyl, &head, §); return reg_pio_data_out(device->bus, device->device, CMD_WRITE_SECTORS, 0, numSectors, cyl, head, sect, data, numSectors, 2);}static void ide_string_conv(char *str, int len){ unsigned int i; int j; for (i=0; i<len/sizeof(unsigned short); i++) { char c = str[i*2+1]; str[i*2+1] = str[i*2]; str[i*2] = c; } str[len - 1] = 0; for (j=len-1; j>=0 && str[j]==' '; j--) str[j] = 0;}// execute a software resetbool ide_reset(void){ unsigned char devCtrl = CB_DC_HD15 | CB_DC_NIEN; // Set and then reset the soft reset bit in the Device // Control register. This causes device 0 be selected pio_outbyte(CB_DC, devCtrl | CB_DC_SRST); DELAY400NS; pio_outbyte(CB_DC, devCtrl); DELAY400NS; return (ide_wait_busy() ? true : false);}// check devices actually exist on bus, and if so what typestatic uint8 ide_drive_present(int bus, int device){ int ret = NO_DEVICE; unsigned char devCtrl = CB_DC_HD15 | CB_DC_NIEN; uint8 sc, sn, ch=0, cl=0, st=0; // set up the device control register pio_outbyte(CB_DC, devCtrl); pio_outbyte(CB_DH, device ? CB_DH_DEV1 : CB_DH_DEV0); DELAY400NS; pio_outbyte(CB_SC, 0x55); pio_outbyte(CB_SN, 0xaa); pio_outbyte(CB_SC, 0xaa); pio_outbyte(CB_SN, 0x55); pio_outbyte(CB_SC, 0x55); pio_outbyte(CB_SN, 0xaa); sc = pio_inbyte(CB_SC); sn = pio_inbyte(CB_SN); // ensure a device exists if(sc == 0x55 && sn == 0xaa) ret = UNKNOWN_DEVICE; // issue a soft bus reset pio_outbyte(CB_DH, CB_DH_DEV0); DELAY400NS; if(ide_reset() == false) dprintf("ide_reset() failed!\n"); // re-select device pio_outbyte(CB_DH, device ? CB_DH_DEV1 : CB_DH_DEV0); DELAY400NS; // test for type of device sc = pio_inbyte(CB_SC); sn = pio_inbyte(CB_SN); if((sc == 0x01) && (sn == 0x01)) { ret = UNKNOWN_DEVICE; cl = pio_inbyte(CB_CL); ch = pio_inbyte(CB_CH); st = pio_inbyte(CB_STAT); if ((cl == 0x14) && (ch == 0xeb)) ret = ATAPI_DEVICE; if ((cl == 0x00) && (ch == 0x00) && (st != 0x00)) ret = ATA_DEVICE; } dprintf("ide_drive_present: sector count = %d, sector number = %d, " "cl = %x, ch = %x, st = %x, return = %d\n", sc, sn, cl, ch, st, ret); return (ret ? ret : NO_DEVICE);}uint8 ata_cmd(int bus, int device, int cmd, uint8* buffer){return reg_pio_data_in(bus, device, cmd, 1, 0, 0, 0, 0, buffer, 1, 0);}uint8 ide_identify_device(int bus, int device){ uint8 *buffer = NULL; ide_device *ide = &devices[(bus*2) + device]; ide->device_type = ide_drive_present(bus, device); ide->bus = bus; ide->device = device;// dprintf("ide_identify_device: type %d, bus %d, device %d\n",// ide->device_type, bus, device); switch (ide->device_type) { case NO_DEVICE: case UNKNOWN_DEVICE: break; case ATAPI_DEVICE: // try for more debug data with optional `identify' command buffer = (uint8*)&ide->hardware_device; if(ata_cmd(bus, device, CMD_IDENTIFY_DEVICE_PACKET, buffer) == NO_ERROR) { ide_string_conv(ide->hardware_device.model, 40); ide_string_conv(ide->hardware_device.serial, 20); ide_string_conv(ide->hardware_device.firmware, 8); dprintf("ide: cd-rom at bus %d, device %d, model = %s\n", bus, device, ide->hardware_device.model); dprintf("ide: cd-rom serial number = %s firmware revision = %s\n", ide->hardware_device.serial, ide->hardware_device.firmware); } break; case ATA_DEVICE: // try for more debug data with optional `identify' command buffer = (uint8*)&ide->hardware_device; if(ata_cmd(bus, device, CMD_IDENTIFY_DEVICE, buffer) == NO_ERROR) { ide->device_type = ATA_DEVICE; ide_string_conv(ide->hardware_device.model, 40); ide_string_conv(ide->hardware_device.serial, 20); ide_string_conv(ide->hardware_device.firmware, 8); ide->sector_count = ide->hardware_device.curr_cyls * ide->hardware_device.curr_heads * ide->hardware_device.curr_sectors; ide->bytes_per_sector = 512; ide->lba_supported = ide->hardware_device.capabilities & DRIVE_SUPPORT_LBA; ide->start_block = 0; ide->end_block = ide->sector_count; // - ide->start_block; dprintf("ide %p: disk at bus %d, device %d, model = %s\n", ide, bus, device, ide->hardware_device.model); dprintf("ide: disk serial number = %s firmware revision = %s\n", ide->hardware_device.serial, ide->hardware_device.firmware); dprintf("ide/%d/%d: %dMB; %d cyl, %d head, %d sec, %d bytes/sec (LBA=%d)\n", bus, device, ide->sector_count * ide->bytes_per_sector / (1000 * 1000), ide->hardware_device.curr_cyls, ide->hardware_device.curr_heads, ide->hardware_device.curr_sectors, ide->bytes_per_sector, ide->lba_supported); } default: ; } return (ide->device_type);}// set the pio base addressesvoid ide_raw_init(unsigned int base1, unsigned int base2){ pio_reg_addrs[CB_DATA] = base1 + 0; // 0 pio_reg_addrs[CB_FR ] = base1 + 1; // 1 pio_reg_addrs[CB_SC ] = base1 + 2; // 2 pio_reg_addrs[CB_SN ] = base1 + 3; // 3 pio_reg_addrs[CB_CL ] = base1 + 4; // 4 pio_reg_addrs[CB_CH ] = base1 + 5; // 5 pio_reg_addrs[CB_DH ] = base1 + 6; // 6 pio_reg_addrs[CB_CMD ] = base1 + 7; // 7 pio_reg_addrs[CB_DC ] = base2 + 6; // 8 pio_reg_addrs[CB_DA ] = base2 + 7; // 9}#if 0static bool ata_get_partition_info(ide_device *device, tPartition *partition, uint32 position){ char buffer[512]; uint8* partitionBuffer = buffer; if (ata_read_sector(device, buffer, position, 1) != NO_ERROR) { dprintf("ata_get_partition_info(): unable to read partition table\n"); return false; } if ((partitionBuffer[PART_IDENT_OFFSET] != 0x55) || (partitionBuffer[PART_IDENT_OFFSET+1] != 0xaa)) { dprintf("ata_get_partition_info(): partition table signature is incorrect\n"); return false; } memcpy(partition, partitionBuffer + PARTITION_OFFSET, sizeof(tPartition) * NUM_PARTITIONS); return true;}bool ata_get_partitions(ide_device *device){ uint8 i, j; memset(&device->partitions, 0, sizeof(tPartition) * MAX_PARTITIONS); if(ata_get_partition_info(device, device->partitions, 0) == false) return false; dprintf("Primary Partition Table\n"); for (i = 0; i < NUM_PARTITIONS; i++) { dprintf(" %d: flags:%x type:%x start:cy%d hd%d sc%d end:cy%d hd%d sc%d lba:%d len:%d\n", i, device->partitions[i].boot_flags, device->partitions[i].partition_type, device->partitions[i].starting_cylinder, device->partitions[i].starting_head, device->partitions[i].starting_sector, device->partitions[i].ending_cylinder, device->partitions[i].ending_head, device->partitions[i].ending_sector, device->partitions[i].starting_block, device->partitions[i].sector_count); } for(j=0; j<4; j++) { if((device->partitions[j].partition_type == PTDosExtended) || (device->partitions[j].partition_type == PTWin95ExtendedLBA) || (device->partitions[j].partition_type == PTLinuxExtended)) { int extOffset = device->partitions[j].starting_block; if(ata_get_partition_info(device, &device->partitions[4], extOffset) == false) return false; dprintf("Extended Partition Table\n"); for (i=NUM_PARTITIONS; i<MAX_PARTITIONS; i++) { device->partitions[i].starting_block += extOffset; dprintf(" %d: flags:%x type:%x start:cy%d hd%d sc%d end:cy%d hd%d sc%d lba:%d len:%d\n", i, device->partitions[i].boot_flags, device->partitions[i].partition_type, device->partitions[i].starting_cylinder, device->partitions[i].starting_head, device->partitions[i].starting_sector, device->partitions[i].ending_cylinder, device->partitions[i].ending_head, device->partitions[i].ending_sector, device->partitions[i].starting_block, device->partitions[i].sector_count); } } } return true;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -