设备驱动与文件系统:01 I/O与显示器

article/2025/8/13 20:40:55

操作系统设备驱动学习之旅——以显示器驱动为例

从这一节开始,我要学习操作系统的第四个部分,就是i o设备的驱动。今天要讲的是第26讲,内容围绕i o设备中的显示器展开,探究显示器是如何被驱动的,也就是操作系统怎样让用户使用显示器,最终会落脚到print f这个函数是如何将内容显示在屏幕上的。

设备驱动基础原理

操作系统是管理计算机硬件的一层软件。在这里插入图片描述
之前,我已经学习了操作系统如何管理cpu,弄清楚了fork以及进程管理的含义,明白了cpu是如何被抽象为进程的;也学习了内存管理相关知识,了解了内存如何分段、分页,以及虚拟内存的引出,直到数据最终写入物理内存。现在,我要开始学习计算机硬件中的另一重要部分——i o设备,这一讲和下一讲主要聚焦键盘和显示器,之后还会涉及磁盘及基于磁盘抽象出的文件系统,但本质上都是i o设备的驱动。
在这里插入图片描述

在学习具体设备驱动前,得先明确计算机让外设工作的原理。这是计算机的基本常识,使用外设时,每个外设都有对应的控制器,比如显示器的显卡。cpu只需向外设控制器中的寄存器或存储区域发送一条指令,控制器就会依据指令内容操控硬件。以显示器为例,cpu给显卡寄存器发指令,显卡就能让显示器显示内容。通常,cpu发出指令后会去执行别的进程,等外设完成任务,会向cpu发送中断信号,cpu再处理中断,可能涉及数据传输等操作。
在这里插入图片描述

总结起来,操作系统让外设工作的核心就两点:一是向控制器发指令,最终表现为类似out的指令;二是处理外设工作完成后的中断。虽然实际操作外设的代码很多,但核心指令就那么几条。之所以有大量代码,是为了让外设使用更简单,这就需要提供统一的视图。因为不同设备的控制器不同,直接操作寄存器很麻烦,不同公司硬件设计也有差异,所以操作系统要形成统一接口,也就是文件视图,这样既能隐藏细节方便用户,内部还能进行高效处理。

简而言之,外设驱动主要做三件事:

  1. 发出out指令,操控设备控制器寄存器;
  2. 进行设备中断处理;
  3. 提供统一文件视图,方便用户使用。

print f显示原理探究在这里插入图片描述

在这里插入图片描述

接下来,我通过print f这个实际例子来深入理解设备驱动。print f本质上是一段操作外设的程序,和其他设备操作一样,遵循统一规则。在linux系统中,操作设备通常表现为openreadwriteprint f也不例外,它打开的是显示器对应的文件,然后进行写入操作。操作系统为用户提供统一的文件接口,通过不同的设备文件名区分操作的设备,print f对应的设备文件名决定了它操作的是显示器。
在这里插入图片描述

具体来看,print f最终会变成系统调用write,写成write(1,buffer,...),这里的1决定了数据输出到显示器,buffer是格式化后的字符串缓冲区。系统调用通过int 0x80进入内核,执行sys_write。这里关键的1是文件描述符,它来自当前进程pcb数组的第一项,这个文件描述符对应一个文件,文件的inode中存放着设备相关信息。
在这里插入图片描述
在这里插入图片描述

那么1对应的文件是怎么来的呢?进程的pcbfork创建时拷贝父进程的,所有进程打开文件的指针都源于父进程。系统初始化时,0号进程创建相关进程,打开了一个文件并拷贝两份,1对应的文件就是dev/tty0tty代表终端设备。open系统调用会根据文件名读入文件的inode信息,操作系统依据这些信息决定后续操作路径。
在这里插入图片描述
在这里插入图片描述

根据inode信息判断设备类型,如果是字符设备,就执行rw_char,并根据设备号继续分支。dev/tty0是字符设备,设备号为4,通过设备号在函数指针数组中找到对应的处理函数rw_ttyx。因为是write操作,所以会调用tty_write函数,这个函数会将数据先写入缓冲区right_q。这涉及到缓冲技术,由于cpu和内存操作速度快,显示器显示速度慢,通过缓冲区可以平衡速度差异,缓冲区就像生产者 - 消费者模型中的共享缓冲区,写满时生产者(数据写入操作)会睡眠等待,不满时则写入数据。
在这里插入图片描述

数据写入缓冲区后,会调用函数从缓冲区取出数据输出到显示器。tty_write函数会继续调用console_writeconsole就是终端设备,即显示器。console_write函数会从缓冲区取出字符c,通过out指令将字符输出到显示器。具体的汇编指令会将字符属性赋给ah,字符赋给alaxahal组成),然后将ax写入显存地址pose。这里涉及内存和i o设备的编址方式,如果是统一编址用mov指令,如果是独立编址用out指令,通常显存较大,采用独立编址,但本质上movout都是对i o设备控制器中的存储区域进行写操作。

总结与实验展望

至此,我梳理清楚了print f的整个过程。从系统调用write开始,通过统一文件接口,依据设备信息逐步找到驱动显示器的函数,利用缓冲技术和相关指令,最终将数据输出到显存显示在屏幕上。设备驱动的核心就是cpu向外设控制寄存器发指令进行读写,并形成统一文件视图方便使用,同时处理中断。相比cpu和内存管理,设备驱动相对简单。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于mov ax,pose中的pose,它每次写完会加2,因为显存存储字符和属性各占一个字节。初始的pose值在系统启动时,通过setup程序根据bios中断取出硬件参数(包括光标位置),将光标所在显存位置存入90000处,初始化时再将其赋值给pose


http://www.hkcw.cn/article/tKvMVjFQeV.shtml

相关文章

【计算机网络】Linux下简单的UDP服务器(超详细)

套接字接口 我们把服务器封装成一个类,当我们定义出一个服务器对象后需要马上初始化服务器,而初始化服务器需要做的第一件事就是创建套接字。 🌎socket函数 这是Linux中创建套接字的系统调用,函数原型如下: int socket(int domain, int typ…

基于微信小程序的云校园信息服务平台设计与实现(源码+定制+开发)云端校园服务系统开发 面向师生的校园事务小程序设计与实现 融合微信生态的智慧校园管理系统开发

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

6月1日星期日今日早报简报微语报早读

6月1日星期日,农历五月初六,早报#微语早读。 1、10个省份城镇化率超70%,广东城镇人口超9700万; 2、长沙居民起诉太平财险不赔“新冠险”,立案878天后获胜判; 3、海口:全市范围内禁止投放互联…

linux命令 systemctl 和 supervisord 区别及用法解读

目录 基础与背景服务管理范围配置文件和管理方式监控与日志依赖管理适用场景常用命令对照表实际应用场景举例优缺点对比小结参考链接 1. 基础与背景 systemctl 和 supervisord 都是用于管理和控制服务(进程)的工具,但它们在设计、使用场景和…

用mediamtx搭建简易rtmp,rtsp视频服务器

简述: 平常测试的时候搭建rtmp服务器很麻烦,这个mediamtx服务器,只要下载就能运行,不用安装、编译、配置等,简单易用、ffmpeg推流、vlc拉流 基础环境: vmware17,centos10 64位,wi…

YOLOv5-入门篇笔记

1.创建环境 conda create -n yolvo5 python3.8 去pytorch.org下载1.8.2的版本。 pip --default-timeout1688 install torch1.8.2 torchvision0.9.2 torchaudio0.8.2 --extra-index-url https://download.pytorch.org/whl/lts/1.8/cu111 github上下载yolov5的zip pip --def…

设计模式-行为型模式-模版方法模式

概述 模板方法模式 :Template Method Pattern : 是一种行为型设计模式. 它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中实现。 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 符合 开闭原则。 可以在算法的流程中&…

barker-OFDM模糊函数原理及仿真

文章目录 前言一、巴克码序列二、barker-OFDM 信号1、OFDM 信号表达式2、模糊函数表达式 三、MATLAB 仿真1、MATLAB 核心源码2、仿真结果①、barker-OFDM 模糊函数②、barker-OFDM 距离分辨率③、barker-OFDM 速度分辨率④、barker-OFDM 等高线图 四、资源自取 前言 本文进行 …

十三、【核心功能篇】测试计划管理:组织和编排测试用例

【核心功能篇】测试计划管理:组织和编排测试用例 前言准备工作第一部分:后端实现 (Django)1. 定义 TestPlan 模型2. 生成并应用数据库迁移3. 创建 TestPlanSerializer4. 创建 TestPlanViewSet5. 注册路由6. 注册到 Django Admin 第二部分:前端…

Python训练第四十一天

DAY 41 简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化:调整一个批次的分布,常用与图像数据特征图:只有卷积操作输出的才叫特征图调度器:直接修改基础学习率 卷积操作常见流程如下: 1. 输入 → 卷积层 →…

【C++进阶篇】哈希表的封装(赋源码)

C哈希表终极封装指南:从线性探测到STL兼容的迭代器魔法 一. 哈希表的封装1.1 基本结构1.1.1 插入1.1.2 查找1.1.3 删除1.1.4 Begin()1.1.5 End()1.1.6 构造函数1.1.7 析构函数 1.2 迭代器设计(重点)1.2.1 重载operator*()1.2.2 重载operator-…

238除自身以外数组的乘积

题目链接: https://leetcode.cn/problems/product-of-array-except-self/description/解法一&#xff1a;暴力解法 直接遍历一遍数组&#xff0c;求该数组的除该数之外的乘积&#xff0c;但是超时时间复杂度为n方。 vector<int> productExceptSelf(vector<int>&a…

主数据编码体系全景解析:从基础到高级的编码策略全指南

在数字化转型的浪潮中&#xff0c;主数据管理&#xff08;MDM&#xff09;已成为企业数字化转型的基石。而主数据编码作为MDM的核心环节&#xff0c;其设计质量直接关系到数据管理的效率、系统的可扩展性以及业务决策的准确性。本文将系统性地探讨主数据编码的七大核心策略&…

C# 类和继承(构造函数的执行)

构造函数的执行 在前一章中&#xff0c;我们看到了构造函数执行代码来准备一个即将使用的类。这包括初始化类的静 态成员和实例成员。在这一章&#xff0c;你会看到派生类对象有一部分就是基类对象。 要创建对象的基类部分&#xff0c;需要隐式调用基类的某个构造函数。继承层…

79. Word Search

题目描述 79. Word Search 回溯 代码一&#xff0c;使用used数组 class Solution {vector<pair<int,int>> directions{{0,1},{0,-1},{1,0},{-1,0}};vector<vector<bool>> used; public:bool exist(vector<vector<char>>& board, st…

大模型备案中语料安全详细说明

《AIGC安全要求》针对语料安全&#xff0c;在语料来源授权合法、安全评估核验、不良语料类型三个方面提出了重点要求&#xff0c;具体要求包括&#xff1a; 1、授权合法 语料的来源需要有合法的、明确的授权&#xff0c;确保其符合“授权、同意、告知”的合法性原则。根据语料…

汽车安全:功能安全FuSa、预期功能安全SOTIF与网络安全Cybersecurity 解析

汽车安全的三重防线&#xff1a;深入解析FuSa、SOTIF与网络安全技术 现代汽车已成为装有数千个传感器的移动计算机&#xff0c;安全挑战比传统车辆复杂百倍。 随着汽车智能化、网联化飞速发展&#xff0c;汽车电子电气架构已从简单的分布式控制系统演变为复杂的移动计算平台。现…

【云安全】以Aliyun为例聊云厂商服务常见利用手段

目录 OSS-bucket_policy_readable OSS-object_public_access OSS-bucket_object_traversal OSS-Special Bucket Policy OSS-unrestricted_file_upload OSS-object_acl_writable ECS-SSRF 云攻防场景下对云厂商服务的利用大同小异&#xff0c;下面以阿里云为例 其他如腾…

[MongoDB] 认识MongoDB以及在Windows和Linux上安装MongoDB

初次学习&#xff0c;如有错误还请指正 目录 MongoDB简介 体系结构 数据模型 MongoDB的特点 Windows中的安装 Linux系统中的安装启动和连接 MongoDB简介 MongoDB是一个开源、高性能、无模式的文档型数据库&#xff0c;当初的设计就是用于简化开发和方便扩展&#xff0c;…

iOS —— UI 初探

简介 第一次新建时&#xff0c;你可能会好奇。为什么有这么多文件&#xff0c;他们都有什么用&#xff1f; App 启动与生命周期管理相关 文件名 类型 作用 main.m m 程序入口&#xff0c;main() 函数定义在这里 AppDelegate.h/.m h/m App 启动/进入后台/退出等全局事…