Esempio n. 1
0
File: ide.c Progetto: YMChenLiye/os
/* 获得硬盘参数信息 */
static void identify_disk(struct disk* hd) {
	char id_info[512];
	select_disk(hd);
	cmd_out(hd->my_channel, CMD_IDENTIFY);
	/* 向硬盘发送指令后便通过信号量阻塞自己,
	 * 待硬盘处理完成后,通过中断处理程序将自己唤醒 */
	sema_down(&hd->my_channel->disk_done);

	/* 醒来后开始执行下面代码*/
	if (!busy_wait(hd)) {     //  若失败
		char error[64];
		sprintf(error, "%s identify failed!!!!!!\n", hd->name);
		PANIC(error);
	}
	read_from_sector(hd, id_info, 1);

	char buf[64];
	uint8_t sn_start = 10 * 2, sn_len = 20, md_start = 27 * 2, md_len = 40;
	swap_pairs_bytes(&id_info[sn_start], buf, sn_len);
	printk("   disk %s info:\n      SN: %s\n", hd->name, buf);
	memset(buf, 0, sizeof(buf));
	swap_pairs_bytes(&id_info[md_start], buf, md_len);
	printk("      MODULE: %s\n", buf);
	uint32_t sectors = *(uint32_t*)&id_info[60 * 2];
	printk("      SECTORS: %d\n", sectors);
	printk("      CAPACITY: %dMB\n", sectors * 512 / 1024 / 1024);
}
Esempio n. 2
0
File: ide.c Progetto: YMChenLiye/os
//从硬盘读取sec_cnt个扇区到buf
void ide_read(struct disk* hd,uint32_t lba,void* buf,uint32_t sec_cnt){
	ASSERT(lba <= max_lba);
	ASSERT(sec_cnt > 0);
	lock_acquire(&hd->my_channel->lock);

	//1、先选择操作的硬盘
	select_disk(hd);

	uint32_t secs_op;				//每次操作的扇区数
	uint32_t secs_done = 0;			//已完成的扇区数
	while(secs_done < sec_cnt){
		if((secs_done + 256) <= sec_cnt){
			secs_op = 256;
		}else{
			secs_op = sec_cnt - secs_done;
		}

		//2、写入待读入的扇区数和起始扇区号
		select_sector(hd,lba + secs_done,secs_op);

		//3、执行的命令写入reg_cmd寄存器
		cmd_out(hd->my_channel,CMD_READ_SECTOR);		//准备开始读数据

		//------------ 阻塞自己的时机  --------------------
		//	在硬盘已经开始工作(开始在内部读数据或写数据)后才能阻塞自己,现在硬盘已经开始忙
		//	了,将自己阻塞,等待硬盘完成读操作后通过中断处理程序唤醒自己
		sema_down(&hd->my_channel->disk_done);
		//-------------------------------------------------

		//4、检测硬盘状态是否可读
		//醒来后开始执行下面代码
		if(!busy_wait(hd)){	//若失败
			char error[64];
			sprintf(error,"%s read sector %d failed!!!!\n",hd->name,lba);
			PANIC(error);
		}

		//5、把数据从硬盘的缓冲区中读出
		read_from_sector(hd,(void*)((uint32_t)buf + secs_done * 512),secs_op);
		secs_done += secs_op;
	}
	lock_release(&hd->my_channel->lock);
}
Esempio n. 3
0
/* 从硬盘读取sec_cnt个扇区到buf */
void ide_read(struct disk* hd, uint32_t lba, void* buf, uint32_t sec_cnt) {   // 此处的sec_cnt为32位大小
    ASSERT(lba <= max_lba);
    ASSERT(sec_cnt > 0);
    lock_acquire (&hd->my_channel->lock);

    /* 1 先选择操作的硬盘 */
    select_disk(hd);

    uint32_t secs_op;		 // 每次操作的扇区数
    uint32_t secs_done = 0;	 // 已完成的扇区数
    while(secs_done < sec_cnt) {
        if ((secs_done + 256) <= sec_cnt) {
            secs_op = 256;
        } else {
            secs_op = sec_cnt - secs_done;
        }

        /* 2 写入待读入的扇区数和起始扇区号 */
        select_sector(hd, lba + secs_done, secs_op);

        /* 3 执行的命令写入reg_cmd寄存器 */
        cmd_out(hd->my_channel, CMD_READ_SECTOR);	      // 准备开始读数据

        /*********************   阻塞自己的时机  ***********************
          在硬盘已经开始工作(开始在内部读数据或写数据)后才能阻塞自己,现在硬盘已经开始忙了,
          将自己阻塞,等待硬盘完成读操作后通过中断处理程序唤醒自己*/
        sema_down(&hd->my_channel->disk_done);
        /*************************************************************/

        /* 4 检测硬盘状态是否可读 */
        /* 醒来后开始执行下面代码*/
        if (!busy_wait(hd)) {			      // 若失败
            char error[64];
            sprintf(error, "%s read sector %d failed!!!!!!\n", hd->name, lba);
            PANIC(error);
        }

        /* 5 把数据从硬盘的缓冲区中读出 */
        read_from_sector(hd, (void*)((uint32_t)buf + secs_done * 512), secs_op);
        secs_done += secs_op;
    }
    lock_release(&hd->my_channel->lock);
}