Dingus 硬盘驱动(简)

网上查找Linux硬盘驱动的话能找到好多相关信息,但是具体代码都没有。经过一番努力,实现了硬盘读写的代码,特来分享一下。可能因为硬盘控制器更新的原因,一些新式的笔记本上使用这些代码会失败。不过在VmWare上是可以用的。这个项目的git地址:git://code.csdn.net/hanjianqiao/dingus.git。在commit为“Add harddisk”的版本直接编译出的镜像便是下面这个。

上图中密密麻麻的16进制数据是从硬盘第一个扇区取出来的,这些数据是在之前就已经写入了硬盘的。最后的55 AA是大家都熟悉的可启动扇区标记。

本来想用一张图来表达硬盘驱动的过程,可是实在没想出来这个图怎么画比较好,就用纯文字了:

写硬盘:

1、向硬盘控制端口输出控制数据,然后发送写命令0x30

2、等待硬盘控制器就绪(可用轮询方式),进行下一步

3、依次向数据端口0x1f0写256字(双字节)数据

4、一轮询方式后中断方式等待硬盘写数据完成

读硬盘:

1、等待硬盘控制器就绪(可用轮询方式),进行下一步

2、向硬盘控制端口输出控制数据,然后发送写命令0x20

3、等待硬盘中断产生

4、硬盘中断产生时,连续从数据端口读256个字。

这里的硬盘控制器就像是售货员一样,当你买东西的时候,你要先告诉她要什么样的商品。然后当售货员取道你想要的东西时就会触发一个中断:这是你要的商品,然后你就能得到你想要的东西。当你退货(相当于写扇区)的时候,你要给售货员说你要退货,然后把东西交给他(把数据写入缓冲),然后售货员把退回的货物放到存储的地方之后触发一个中断,你就知道货已成功退掉了。

下面上代码:

void init_harddisk(){
	unsigned char cw;
	struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT;
	cw = io_in8(PIC1_IMR);
	cw = cw & 0xbf;
	io_out8(PIC1_IMR, cw);
	set_gatedesc(idt + 0x2e, (int) asm_inthandler2e, 2 * 8, AR_INTGATE32);
	return;
}

这段代码和前面的鼠标驱动,键盘驱动的初始化差不多,都是使能中断并配置中断响应函数。

static int controller_ready (void)
{
	int retries = 10000;

	while (--retries && (io_in8(0x1f7) & 0xc0) != 0x40);
		return (retries);		// 返回等待循环的次数。
}

这个相当于延时函数。

接着就是主要的函数了:

void readHardDisk(unsigned char nsector, unsigned char sector, unsigned int cyl, unsigned char current){
	struct BOOTINFO	*binfo = (struct BOOTINFO	*) ADR_BOOTINFO;
	int	i;
	i = controller_ready();
	if(i == 0){
		putfonts8_asc(binfo->vram, binfo->scrnx, 400,	400, COL8_00FF00,	"Read Busy");
		putHex(binfo->vram, binfo->scrnx, 480,	400, COL8_00FF00,	io_in8(0x1f7));
		putHex(binfo->vram, binfo->scrnx, 520,	400, COL8_00FF00,	io_in8(0x1f1));
		return;
	}
	io_out8(0x3f6, 0x00);
	io_out8(0x1f2, nsector);
	io_out8(0x1f3, sector);
	io_out8(0x1f4, cyl);
	io_out8(0x1f5, cyl>>8);
	io_out8(0x1f6, current | 0xa0);
	io_out8(0x1f7, 0x20);
}

void writeHardDisk(unsigned char nsector, unsigned char sector, unsigned int cyl, unsigned char current, short* buf){
	struct BOOTINFO	*binfo = (struct BOOTINFO	*) ADR_BOOTINFO;
	int	i;
	i = controller_ready();
	if(i == 0){
		putfonts8_asc(binfo->vram, binfo->scrnx, 400,	400, COL8_00FF00,	"Busy");
		return;
	}
	io_out8(0x1f2, nsector);
	io_out8(0x1f3, sector);
	io_out8(0x1f4, cyl);
	io_out8(0x1f5, cyl>>8);
	io_out8(0x1f6, current | 0xa0);
	io_out8(0x1f7, 0x30);
	i = controller_ready();
	if(i == 0){
		putfonts8_asc(binfo->vram, binfo->scrnx, 400,	400, COL8_00FF00,	"Busy in writing");
		return;
	}
	for(i	=	0; i < 256;	i++){
		io_out16(0x1f0, buf[i]);
	}
}

void inthandler2e(int	*esp){
	struct BOOTINFO	*binfo = (struct BOOTINFO	*) ADR_BOOTINFO;
	int	i;
	short	hd_data[256];
	for(i	=	0; i < 256;	i++){
		hd_data[i] = io_in16(0x1f0);
	}
	//*((unsigned char *)hd_data) = io_in8(0x1f7);
	putHexs(binfo->vram, binfo->scrnx, 0,	0, COL8_00FF00,	(unsigned	char *)hd_data,	512);
	io_out8(PIC1_OCW2, 0x66);
	io_out8(PIC0_OCW2, 0x62);
	return;
}

可能看到0x1f0大家会莫名其妙,下面就是对这些端口的介绍。想查看更详细的说名可以参照赵炯老师写的《Linux内核完全注释》这本书。

1、向硬盘控制端口输出控制数据,然后发送写命令0x30

2、等待硬盘控制器就绪(可用轮询方式),进行下一步

Dingus 硬盘驱动(简)

时间: 2024-12-09 01:25:54

Dingus 硬盘驱动(简)的相关文章

linux硬盘驱动更新

作者:邹祁峰 邮箱:[email protected] 博客:http://blog.csdn.net/qifengzou 日期:2015.01.16 00:33 转载请注明来自"祁峰"的CSDN博客 在内核未升级之前,系统能够正常启动和使用,而当升级系统内核后,系统却无法正常启动时,这可能是因为硬盘驱动不兼容造成的.现可通过进入旧系统按照以下步骤逐步排查相关原因: ①.查询硬盘控制芯片厂商和型号 #lspci -nn | grep "SAS" #lspci -nn

在vmware esxi6.5中将硬盘驱动类型由HDD变为SSD类型

环境:在vmware web client6.5中的主机,主机IP为10.1.1.47 目的:为配置VSAN,需将所创建的三块硬盘类型的一块变成SSD类型,作为缓冲. 步骤1:将主机的SSH打开,以使xshell进行连接,配置->安全配置文件->编辑 将ESXI Shell 和SSH手动打开 将锁定模式禁用,配置->安全配置文件->锁定模式 使用xshell进行连接 输入密码即可登录 步骤2:更改硬盘驱动类型 esxcli storage core device list 找到目标

对于硬盘驱动的理解

目录 如何读写硬盘 读写操作 硬盘控制器端口及作用 硬盘中断 硬盘分区信息的获取 如何读写文件 TASK_HD 如何读写硬盘 读写操作 第一次看到linux 0.12关于读写硬盘几行代码时候,感觉很费解. do_hd = intr_addr; outb_p(hd_info[drive].ctl,HD_CMD); port=HD_DATA; outb_p(nsect,++port); outb_p(sect,++port); outb_p(cyl,++port); outb_p(cyl>>8,+

KVM下windows虚拟机使用virtio驱动

KVM下windows虚拟机默认disk使用的是Qemu IDE硬盘,网卡默认是rtl8139网卡.为了使kvm主机在相同的配置下,有更好的效率,可以将网卡和磁盘替换成virtio的驱动. windows的virtio驱动主要包括网卡以及磁盘的驱动,主要有三种方式,第一种是已有windows的操作系统,需要更新驱动,第二种是是安装时加载virtio驱动,第三种是直接制作virtio驱动的iso系统镜像. 一:更新virtio驱动 1.修改xml文件 原始xml文件 <disk type='fil

如何在RHEL5系统下挂载NTFS文件格式的USB硬盘

很多安装软件会存储在USB硬盘里面,在Windows系统中,则意味着,该USB硬盘驱动必须使用NTFS格式,因为FAT32格式的最大文件大小是4GB.然而,这里又会碰到新问题,因为在RHEL5中,默认不支持NTFS格式,换一句话说,就不能挂载文件格式为NTFS的USB硬盘.不过这里有个权益之计(work around),被称作'ntfs-3g', 要使其生效,必须安装下面RPM包. NOTE: 使用的版本必须和Linux kernerl module相匹配,可以用uname -r来查看kerne

烂泥:KVM安装Windows Server 2008 R2使用virtio硬盘

本文首发于烂泥行天下. 在上一篇文章中,我们介绍了使用IDE硬盘来安装Windows Server 2008 R2,这篇文章我们来介绍使用virtio硬盘来安装Windows Server 2008 R2. 说明:KVM默认使用的硬盘格式为virtio. 使用virtio接口的硬盘,我们必须加载virtio硬盘驱动.如果不加载该驱动windows installer会无法找到虚拟磁盘,如下图: 现在安装虚拟机的安装步骤,首先创建虚拟机的硬盘,使用如下命令: qemu-img create -f

同一个硬盘安装win10+ubuntu双系统

记录下最近准备玩下ubuntu而 折腾系统的状态 华擎B150M Combo-G+240SSD 64G win10 +36G ubuntu  + 其余存储和装win应用 一.装win10 1.去MSDN下载镜像  64位 多版本 简体中文 http://itellyou.cn/ 2.使用软碟通(UltraISO)制作win10镜像U盘启动盘. 文件->打开镜像->启动->写入硬盘映像->写入 即可 3.插入u盘->开机->按Del或F11进入UEFI设置(以前的主板叫B

虚拟块驱动编写

块设备驱动: 内核中自带的nand 驱动程序通过它来了解,在工作中最多做的是分区表. 1.在linux内核中常见的块设备:磁盘,SD卡,FLASH(NOR),NAND.Linux内核中最早出现的块设备驱动时硬盘驱动,后续出现的支持SD卡,flash驱动程序都是从硬盘驱动衍生出来的 2.块设备为什么需要缓冲机制? 带磁头 不带磁头 3.内核中块设备的机制? 用户空间:有一系列read(write)操作通过系统调用到内核中每一次I/O操作在内核中缓存成一个bio结构,每次I/O操作对应一个boi结构

disk磁盘管理与Linux驱动编写

磁盘管理 一.关于硬盘接口 安装linux red hat系统,到分区时发现硬盘驱动器设备 /dev/sda             #sata接口设备名 /dev/sda1 #sda对应的物理分区 /dev/sda2 /dev/sda3 而又的安装时硬盘驱动设备名为 /dev/hda #IDE接口设备目录 /dev/hda1 sda和hda有什么区别那? HDA是使用了ide接口的硬盘的名称.SDA是sata接口的硬盘的名称.在最新的2.6.19内核里,所有的硬盘都叫SDA了. GERUB里填