/* @param drive When drive == 0, master is selected When drive == 1 slave is selected*/ PUBLIC void kernelHdIdentify(int drive) { struct hd_cmd cmd; cmd.device = MAKE_DEVICE_REG(0, drive, 0); cmd.command = ATA_IDENTIFY; hd_cmd_out(&cmd); hdIdentifyBlockEip = p_proc_running - proc_table; kernelBlock(); port_read(REG_DATA, hdbuf, SECTOR_SIZE); //analysis_identify_info((u16*)hdbuf); }
PUBLIC VirtualKey kernelReadKey() /* 从vk缓冲区中读取下一个字节 */ { VirtualKey key; while (vk.count <= 0){ readKeyBlockEip = (p_proc_running - proc_table); kernelBlock(); } key = *(vk.p_tail); vk.p_tail++; if (vk.p_tail == vk.buf + KB_IN_BYTES) { vk.p_tail = vk.buf; } vk.count--; return key; }
/***************************************************************************** * get_part_table ***************************************************************************** * <Ring 1> Get a partition table of a drive. * * @param drive Drive nr (0 for the 1st disk, 1 for the 2nd, ...)n * @param sect_nr The sector at which the partition table is located. * @param entry Ptr to part_ent struct. *****************************************************************************/ PRIVATE void get_part_table(int drive, int sect_nr, struct part_ent * entry) { struct hd_cmd cmd; cmd.features = 0; cmd.count = 1; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, /* LBA mode */ drive, (sect_nr >> 24) & 0xF); cmd.command = ATA_READ; hd_cmd_out(&cmd); hdIdentifyBlockEip = p_proc_running - proc_table; kernelBlock(); asm("sti"); port_read(REG_DATA, hdbuf, SECTOR_SIZE); memcpy(entry, hdbuf + PARTITION_TABLE_OFFSET, sizeof(struct part_ent) * NR_PART_PER_DRIVE); }
PUBLIC void kernelHdRead(u32 device, u64 position, u32 count, char* buf) { // hd_status = in_byte(REG_STATUS); // disp_str("before hd_status="); // disp_int(hd_status); // disp_str("\n"); device = 0; int drive = DRV_OF_DEV(device); // disp_str("hdRead position: "); // disp_int(position); // if((position & 0x1FF) != 0) // disp_str("we only allow to R/W from a SECTOR boundary\n"); int offset_in_block = position & 0x1FF; u32 sect_nr = (u32)(position >> SECTOR_SIZE_SHIFT); int logidx = (device - MINOR_hd1a) % NR_SUB_PER_DRIVE; sect_nr += device < MAX_PRIM ? hd_info[drive].primary[device].base : hd_info[drive].logical[logidx].base; struct hd_cmd cmd; cmd.features = 0; cmd.count = (offset_in_block + count + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); cmd.command = ATA_READ; hd_cmd_out(&cmd); asm("cli"); int bytes_left = count; // disp_int(count); char** pbuf = &buf; char blockBuf[SECTOR_SIZE] = {'\0'}; int firstFlag = 1; while(bytes_left > 0){ // disp_str("in hd loop@@@"); // disp_str("hd, byte_lefs="); // disp_int(bytes_left); int bytes = ((SECTOR_SIZE - offset_in_block) < bytes_left )? (SECTOR_SIZE - offset_in_block) : bytes_left; // disp_str("hd loop,bytes="); // disp_int(bytes); // // disp_str("hd loop,beytes_left="); // disp_int(bytes_left); hdIdentifyBlockEip = p_proc_running - proc_table; kernelBlock(); port_read(REG_DATA, blockBuf, SECTOR_SIZE); if(!firstFlag) offset_in_block = 0; else firstFlag = 0; memcpy(*pbuf, &(blockBuf[offset_in_block]), bytes); bytes_left -= bytes; *pbuf += bytes; // disp_str("hd loop,beytes_left="); // disp_int(bytes_left); } }
PUBLIC void kernelHdWrite(u32 device, u64 position, u32 count, char* buf) { // disp_int((void*) kernelHdWrite); // hd_status = hd_status & 0xf7; // disp_str("after hd_status="); // disp_int(hd_status); // disp_str("\n"); // out_byte(REG_STATUS, hd_status); // hd_status = in_byte(REG_STATUS); // int drive = DRV_OF_DEV(device); // // // if((position & 0x1FF) != 0) // { // disp_str("we only allow to R/W from a SECTOR boundary\n"); // } // // u32 sect_nr = (u32)(position >> SECTOR_SIZE_SHIFT); // int logidx = (device - MINOR_hd1a) % NR_SUB_PER_DRIVE; // sect_nr += device < MAX_PRIM ? // hd_info[drive].primary[device].base : // hd_info[drive].logical[logidx].base; // // struct hd_cmd cmd; // cmd.features = 0; // cmd.count = (count + SECTOR_SIZE - 1) / SECTOR_SIZE; // disp_str("count: "); // disp_int(cmd.count); // cmd.lba_low = sect_nr & 0xFF; // disp_str("\nlba_low: "); // disp_int(cmd.lba_low); // cmd.lba_mid = (sect_nr >> 8) & 0xFF; // disp_str("\nlba_mid: "); // disp_int(cmd.lba_mid); // cmd.lba_high = (sect_nr >> 16) & 0xFF; // disp_str("\nlba_high: "); // disp_int(cmd.lba_high); // cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); // disp_str("\ndevice: "); // disp_int(cmd.device); // cmd.command = ATA_WRITE; // disp_str("\ncommand: "); // disp_int(cmd.command); // disp_str("\n"); // hd_cmd_out(&cmd); // asm("sti"); // // disp_str("cmd out"); // int bytes_left = count; // while(bytes_left > 0){ // int bytes = (SECTOR_SIZE < bytes_left) ? SECTOR_SIZE : bytes_left; // // if(!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) // disp_str("hd writing error.\n"); // // port_write(REG_DATA, buf, bytes); // hdIdentifyBlockEip = p_proc_running - proc_table; // disp_int(hdIdentifyBlockEip); // disp_str("before block!\n"); // asm("cli"); // kernelBlock(); // asm("sti"); // disp_str("after block!\n"); // bytes_left -= bytes; // buf += bytes; // } int drive = DRV_OF_DEV(device); u64 pos = position; u32 sect_nr = (u32)(pos >> SECTOR_SIZE_SHIFT); int logidx = (device - MINOR_hd1a) % NR_SUB_PER_DRIVE; sect_nr += device < MAX_PRIM ? hd_info[drive].primary[device].base : hd_info[drive].logical[logidx].base; struct hd_cmd cmd; cmd.features = 0; cmd.count = (count + SECTOR_SIZE - 1) / SECTOR_SIZE; cmd.lba_low = sect_nr & 0xFF; cmd.lba_mid = (sect_nr >> 8) & 0xFF; cmd.lba_high = (sect_nr >> 16) & 0xFF; cmd.device = MAKE_DEVICE_REG(1, drive, (sect_nr >> 24) & 0xF); cmd.command = ATA_WRITE; hd_cmd_out(&cmd); int bytes_left = count; while(bytes_left > 0){ int bytes = (SECTOR_SIZE < bytes_left) ? SECTOR_SIZE : bytes_left; if(!waitfor(STATUS_DRQ, STATUS_DRQ, HD_TIMEOUT)) disp_str("hd writing error.\n"); port_write(REG_DATA, buf, bytes); hdIdentifyBlockEip = p_proc_running - proc_table; kernelBlock(); bytes_left -= bytes; buf += bytes; } }
PUBLIC int sysBlock() { kernelBlock(); }