linux0.11内核源码修仙传第十一章——硬盘初始化

news2025/3/31 22:42:51

🚀 前言

    本文是初始化最后一部分了,对硬盘的初始化,对应于书中的第20回。希望各位给个三连,拜托啦,这对我真的很重要!!!

目录

  • 🚀 前言
  • 🏆块设备管理
  • 🏆块设备初始化
  • 🏆块设备读取
  • 🎯总结
  • 📖参考资料

🏆块设备管理

    关于块设备,可以参考之前的博客:linux0.11内核源码修仙传第七章——块设备请求项初始化。在内核中管理块设备采用了一个结构体blk_dev进行管理,每一个索引表示一个块设备,每一个块设备的详细含义如下注释所示:

struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
	{ NULL, NULL },		/* 表示没有块设备,访问会返回错误或者提示无有效设备 */
	{ NULL, NULL },		/* 内存设备 */
	{ NULL, NULL },		/* 软盘设备 */
	{ NULL, NULL },		/* 硬盘设备 */
	{ NULL, NULL },		/* 特定的终端设备 */
	{ NULL, NULL },		/* 终端设备 */
	{ NULL, NULL }		/* 打印机设备 */
};

    从上面的定义可以看到,索引为3的位置(第四个)表示硬盘。这个数组里面每个成员的定义如下:

struct request {
	int dev;		/* -1 if no request */
	int cmd;		/* READ or WRITE */
	int errors;
	unsigned long sector;
	unsigned long nr_sectors;
	char * buffer;
	struct task_struct * waiting;
	struct buffer_head * bh;
	struct request * next;
};

struct blk_dev_struct {
	void (*request_fn)(void);		// 处理函数
	struct request * current_request;	// 块设备的请求
};

    结合上面的blk_dev数组,可以发现一个有意思的事情:每个块设备执行读写请求都有自己的函数,在上层看来都是一个统一函数request_fn,具体实现各有不同,对于硬盘来说,这个实现就是do_hd_request函数。换句话说,只要初始化了所有块设备的request_fn函数指针是哪个处理函数,后面就可以直接调用对应块设备的request_fn,而无需关心具体我该调用哪个函数名字。这个就是多态思想在C语言的体现。也就是C++中的父类指针request_fn指向子类对象do_hd_request,或者Java中的父类引用指向子类对象。

🏆块设备初始化

    下面说完前置的一些信息,来看具体的初始化函数:

void hd_init(void)
{
	blk_dev[3].request_fn = do_hd_request;
	set_intr_gate(0x2E,&hd_interrupt);
	outb_p(inb_p(0x21)&0xfb,0x21);
	outb(inb_p(0xA1)&0xbf,0xA1);
}

    首先像上一节所讲的,设置了硬盘设备的request_fn 所对应的函数。之后设置了一个中断,中断号为0x2E,中断处理函数是hd_interrupt。也就是说,当硬盘发生读写时,硬盘会发出中断信号给CPU,之后CPU陷入中断处理程序。

    这里有个区分,上面设置了一个do_hd_request,下面中断设置了一个hd_interrupt。这两个函数是不一样的,上面是发送请求的函数,下面的函数是读取中断。打个比方:一个是请假的打报告阶段,一个是实际请假后休假的阶段。

    回到初始化函数里面,最后就是往IO端口上读写,作用是允许硬盘控制器发送中断请求信号

🏆块设备读取

    这里给个引子,如何读取硬盘上的数据。首先看硬盘的端口表:
在这里插入图片描述
    读硬盘就是,往除了第一个以外的后面几个端口写数据,告诉要读硬盘的哪个扇区,读多少。然后再从 0x1F0 端口一个字节一个字节的读数据。这就完成了一次硬盘读操作。更具体如下:

0x1F2 写入要读取的扇区数
0x1F3 ~ 0x1F6 这四个端口写入计算好的起始 LBA 地址
0x1F7 处写入读命令的指令号
不断检测 0x1F7 (此时已成为状态寄存器的含义)的忙位
如果第四步骤为不忙,则开始不断从 0x1F0 处读取数据到内存指定位置,直到读完

    代码的话如下所示:

static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
		unsigned int head,unsigned int cyl,unsigned int cmd,
		void (*intr_addr)(void))
{
	···
	port=0x1f0;
	outb_p(hd_info[drive].wpcom>>2,++port);	// 0x1f1,错误寄存器
	outb_p(nsect,++port);					// 0x1f2,扇区计数器
	outb_p(sect,++port);					// 0x1f3,扇区号寄存器
	outb_p(cyl,++port);						// 0x1f4,磁道数低8位
	outb_p(cyl>>8,++port);					// 0x1f5,磁道数高8位
	outb_p(0xA0|(drive<<4)|head,++port);	// 0x1f6,驱动器
	outb(cmd,++port);						// 0x1f7,命令
}

🎯总结

    到这里,初始化就都结束了,目前为止的中断如下所示:

中断号中断处理函数
0 ~ 0x10trap_init 里设置的一堆
0x20timer_interrupt
0x21keyboard_interrupt
0x80system_call
0x2Ehd_interrupt

    整个操作系统就是一个靠中断驱动的死循环而已,如果不发生任何中断,操作系统会一直在一个死循环里等待。换句话说,让操作系统工作的唯一方式,就是触发中断。


📖参考资料

[1] linux源码趣读
[2] 一个64位操作系统的设计与实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2323775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

包络解调在故障诊断中的应用-广义检波解调案例

前言 前面我们曾介绍过广义检波解调的原理&#xff0c;那么今天就将学过的知识点真正用在故障诊断上&#xff0c;由于工厂数据集不能轻易获取&#xff0c;因此通过实验室仿真数据集来介绍整个诊断流程。 数据集 加拿大渥太华是故障诊断领域蛮出名的一个数据集&#xff0c;其…

喜报|迪捷软件入选工信部“2024年信息技术应用创新解决方案”

为进一步深化行业信息技术应用创新&#xff0c;健全信息技术应用创新产业生态&#xff0c;加快新技术新产品应用推广&#xff0c;强化应用牵引和需求导向&#xff0c;加强区域联动和资源整合&#xff0c;工业和信息化部网络安全产业发展中心&#xff08;工业和信息化部信息中心…

2.Python 计算机二级题库:选择题答案解析

一 对 题目1 题目2 题目3 补充&#xff1a;在 Python 中&#xff0c;数字类型的复数类型是 complex。 题目4 题目5 题目6 题目7 题目8 题目9 题目10 题目11 题目12 题目13 题目14 题目15 题目16 题目17 题目18 题目19 题目20 题目21 题目22 题目23 题目24 题目25 题目26 题目27…

使用Selenium和lxml库搜房网爬取某地区房屋信息(python、pycharm爬虫)

一、地址&#xff1a; url "https://zb.newhouse.fang.com/house/s/b91" # 第一页的 URL 但是这个爬虫我不知道为啥总是翻不了页数&#xff0c;请帮忙修改一下~ 二、用到的知识点以及代码详解&#xff1a; 这段代码是一个使用Selenium和lxml库实现的网页爬虫&a…

大模型训练过程中KVCache与MLA

基础内容 在Transformer模型中&#xff0c;每个token有qkv三个属性&#xff0c;分别通过神经网络变换得到。1 根据Transformer中注意力公式&#xff0c;每个token的q需要和之前所有的k计算注意力&#xff0c;然后经过Softmax函数后乘以之前所有token的V&#xff0c;得到最终的…

材质及制作笔记

基本流程&#xff1a; 建中模——zb雕刻高模——maya拓扑低模——拆uv——sp烘焙贴图——sp绘制材质——渲染 1 材质贴图&#xff1a; diffuse/albedo/basecolor&#xff1a;漫反射 reflection/specular&#xff1a;反射 metalness&#xff1a;金属度 glossiness&#xf…

语音机器人与智能体结合

自从春节期间deepseek的发布&#xff0c;大家对语音机器人接入大模型格外的关注。最近又收到一个需求&#xff0c;是语音机器人与智能体的结合。 什么是智能体&#xff1f; 智能体&#xff08;Agent&#xff09;是指能够感知环境并采取行动以实现目标的实体。根据其复杂程度&am…

Axios企业级封装实战:从拦截器到安全策略!!!

&#x1f680; Axios企业级封装实战&#xff1a;从拦截器到安全策略 &#x1f527; 核心代码解析 // 创建Axios实例 const service axios.create({baseURL: api, // &#x1f310; 全局API前缀timeout: 0, // ⏳ 永不超时&#xff08;慎用&#xff01;&#xff09;withCrede…

Zerotier虚拟局域网在树莓派的应用和Syncthing配合Zerotier实现端到端文件同步

一、Zerotier的部署 1、官网注册账号 https://my.zerotier.com/i 2、选择linux系统&#xff0c;执行安装Zerotier curl -s https://install.zerotier.com | sudo bash3、将树莓派网络加入Zerotier zerotier-cli join DB62228FEDF6CE55DB62228FEDF6CE55 为你的Zerotier IP 需…

51c嵌入式~三极管~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12208603 一、PNP与NPN两种三极管使用方法 分享这篇文章总结下关于NPN和PNP两种型号三极管的使用和连接方法。 在单片机应用电路中三极管主要的作用就是开关作用。 PNP与NPN两种三极管使用方法 上图中&#xff0c;横向左…

SQL中累计求和与滑动求和函数sum() over()的用法

[TOC](SQL中累计求和与滑动求和函数sum() over()的用法) 一、窗口函数功能简介 sum(c) over(partition by a order by b) 按照一定规则汇总c的值&#xff0c;具体规则为以a分组&#xff0c;每组内按照b进行排序&#xff0c;汇总第一行至当前行的c的加和值。 sum()&#xff1a…

【Sql Server】在SQL Server中生成雪花ID(Snowflake ID)

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言认识雪花ID…

FPGA——分秒计数器设计(DE2-115开发板)

一、项目创建 1.创建工程 点击File->New Project Wizard...或者直接在页面处点击 在第一行选择文件存放地点&#xff0c;第二行为项目名称&#xff0c;第三行为顶级设计实体名称 &#xff08;下面的步骤可以暂时不做直接点Finish&#xff0c;因为是先写代码先把它跑出来暂…

雅思练习总结(九)

雅思练习总结&#xff08;九&#xff09; 本文章是雅思练习总结&#xff08;九&#xff09;&#xff0c;总结了文章《BAKELITE》&#xff0c;内容包括原文精翻&#xff0c;文章脉络总结&#xff0c;单词扩展学习3个部分 1 文章原文及翻译 BAKELITE 翻译&#xff1a;贝克莱特…

windows USB 了解

GUID GUID 是一个 128 位的数字&#xff0c;在全球范围内是独一无二的&#xff0c;常被用于标识软件组件、设备接口等&#xff0c;以保证在不同系统和环境中能唯一识别特定对象。 DEFINE_GUID(GUID_DEVINTERFACE_USCUSTOMKEYS, 0x12345678, 0x1234, 0x5678, 0x12, 0x12, 0x23…

光谱相机的光谱信息获取

光谱信息的获取方式主要依赖于不同分光技术和成像方法&#xff0c;将入射光分解为不同波长并记录其强度。以下是常见的光谱信息获取技术分类及原理&#xff1a; ‌1. 分光技术&#xff08;物理分解波长&#xff09;‌ ‌(1) 滤光片法‌ ‌原理‌&#xff1a;使用固定或可调滤…

免去繁琐的手动埋点,Gin 框架可观测性最佳实践

作者&#xff1a;牧思 背景 在云原生时代的今天&#xff0c;Golang 编程语言越来越成为开发者们的首选&#xff0c;而对于 Golang 开发者来说&#xff0c;最著名的 Golang Web 框架莫过于 Gin [ 1] 框架了&#xff0c;Gin 框架作为 Golang 编程语言官方的推荐框架 [ 2] &…

构建大语言模型应用:简介(第一部分)

本专栏聚焦大语言模型&#xff08;LLM&#xff09;相关内容的解析&#xff0c;通过检索增强生成&#xff08;RAG&#xff09;应用的视角来进行。 本系列文章 简介&#xff08;本文&#xff09;数据准备句子转换器向量数据库搜索与检索大语言模型开源检索增强生成评估大语言模…

PEmicro Multilink FX调试踩坑

文章目录 1.背景2 功能说明2.1 实时数据查看功能2.1 电压观测2.2 SWO功能 3 设置与支持 1.背景 既然使用了NXP的芯片&#xff0c;笔者就想使用一下它的专用调试器&#xff0c;这里先说一下&#xff0c;笔者是从朋友那里借了一个调试器&#xff0c;型号为PEmicro Multilink FX …

主流大模型采用的架构、注意力机制、位置编码等汇总表

记录下主流大模型的一些核心知识点&#xff0c;包括&#xff1a; 架构注意力机制位置编码归一化激活函数模型参数 表中的一些模型已经是很久之前的了&#xff0c;比如表中并未收入 DeepSeek V3 中使用的MLA的注意力机制。先占个位&#xff0c;后续如果有更新的汇总表再来更…