예제 #1
0
/* @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);
}
예제 #2
0
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;
}
예제 #3
0
/*****************************************************************************
 *                                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);
}
예제 #4
0
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);
	}
}
예제 #5
0
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;
	}
}
예제 #6
0
PUBLIC int sysBlock()
{
	kernelBlock();
}