尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Linux内核——多任务内核程序head.s 源码详解
Linux内核完全注释:基于0.11内核(修正版V3.0) 的第四章,最后一节的实验,多任务内核程序head.s 源码详解# 多任务内核程序 [32] 位的启动代码# 包含32位模式下的初始化设置代码,时钟中断代码,系统调用中断代码和两个任务代码LATCH=11930SCRN_SEL=0x18# 屏幕显示内存段选择符。# 问:以下这些选择符是怎么定的值?根据段选择符的定义:位bit[15-3]为段索引,位bit[2]为0表示GDT,1表示LDT,bit[1-0]表示RPL。所以0x18二进制为[00011 0 00]表示GDT表中的第三个描述符。TSS0_SEL=0X20# 任务0的TSS段选择符。 0x20二进制为[00100 0 00],表示选择GDT表中的第四个描述符LDT0_SEL=0X28# 任务0的LDT段选择符。 0x28二进制为[00101 0 00],表示选择GDT表中的第五个描述符TSS1_SEL=0X30# 任务1的TSS段选择符。 0x30二进制为[00110 0 00],表示选择GDT表中的第六个描述符LDT1_SEL=0X38# 任务1的LDT段选择符。 0x38二进制为[00111 0 00],表示选择GDT表中的第七个描述符.global startup_32 .text# 表示可执行代码段(问:实际在编译时有什么影响吗?.text,.data,.bss,用于分别定义当前代码段,数据段和未初始化数据段,# 在链接多个目标模块时,链接程序会根据它们的类别把各个目标模块中的相应段分别组合在一起。)startup_32:# 首先加载 数据段寄存器DS、堆栈段寄存器SS和堆栈指针ESP。所有段的线性基地址都是0.movl$0x10, %eax# 段选择子 0x10 = 00010 0 00 根据段选择符的定义(从左向右分析:00010 表示段索引,0 表示在GDT表查找, 00 表示后三位表示RPL(Ring0-3),在GDT表中查找 第00010个的段描述符 ) # ???上面的赋值,感觉没啥卵用, 当然 0x10, 在下面的 gdt定义里面有, 是 可读写的数据段???mov %ax, %ds# 将eax的低16位(ax)赋给ds寄存器。当指令中没有指定所操作数据的段时,那么DS将是数据段寄存器lss init_stack, %esp# init_stack地址值的低16位传入esp,高16位传入ss.# ???lss mem, reg = mem的低字-reg, mem的高位-段,这里是 ss# 并且, 所以这里是加载了 16+32个字节一共, lss是把前4个字节加载到esp, 后2个字节加载到ss = 0x10 , 堆栈段必须可读写,所以这里用了内核空间的数据段0x10,???# esp-init_stack的地址, 它的上面有 128 * 4 字节的零值,作为栈空间来使用.call setup_idt# 设置中断向量表call setup_gdt# 设置全局描述符表movl$0x10, %eax# 重新设置GDT表后,虽然段选择符没变,但是实际的描述表位置已经改变 (感觉boot.s里的idt和gdt没啥用啊)# (setup_gdt子程序中用lgdt指令更新了GDTR寄存器中gdt表的位置和长度),所以要重新加载段寄存器mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs# 上面所有的段寄存器, 存的都是 内核数据段选择子 0x10; (当然除了CS,这个不能直接设置的)lss init_stack, %esp# 重新加载ss esp# ################################## 设置 时钟芯片 10ms 一次中断信号 ############################# 设置8253定时芯片。把计数器通道0,设置成每隔10毫秒向中断控制器发送一个中断信息号# 下面介绍一下8253定时芯片:# 计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ , 所以把 1193180 /100 = 11931.8 ≈ 11930 赋值给计数器, 收到11931.8 次信号,记作一个周期。也就是周期 0.01s = 10ms# 8253具有3个独立的计数通道,采用减1计数方式。在门控信号有效时,每输入1个计数脉冲,通道做1次计数操作。当计数脉冲是已知周期的时钟信号时,计数就成为定时。# 方式3为:方波发生器,最适合计算机。movb$0x36, %al# 控制字:设置通道0工作在方式3、计数器初值采用二进制。movl$0x43, %edx# 8253芯片控制字寄存器写端口。outb %al, %dx# 向I/O端口写入一个字节,这里是向端口0x43写入0x36movl$LATCH, %eax# 初始计数值设置为LATCH(1193180/100),即频率100HZmovl$0x40, %edx# 通道0的端口。outb %al, %dx# 分两次把初始计数值写入通道0.movb %ah, %al outb %al, %dx# 上面的这个, 了解下就可以,就是为了设置 8253的工作方式而已# ###### 在IDT表第8和第128(0x80)项处分别设置定时中断门描述符和系统调用陷阱门描述符。# ##### 设置定时中断门描述符 ###### 为IDT表(中断描述符表)的第8项,设置中断门描述符(目的是发生该中断,可以调用到设置好的处理程序# 这里先解释一下int $0x80:# int $0x80是一条ATT语法的中断指令,用于Linux的系统调用。# Linux系统下的汇编语言用ATT的语法,如果翻译成Intel的语法就是int 80h,就像我们在Intel的语法下的DOS汇编中经常用的int 21h调用DOS中断,同样如果换成ATT语法就是int $0x80。# 不过无论使用那一种语法,int $0x80或者int 80h都是针对Linux的,在DOS或者Windows下不起相应作用。反之亦然。movl$0x00080000, %eax# eax的值将被用于设置到门描述符的低32位。根据门描述符的格式,0x0008 对应的是段选择符。# 根据 段选择符的格式,0x0008 = 0b1 0 00, 表示gdt表中第二个描述符, 内核的代码段movw$timer_interrupt, %ax# 设置eax的低16位,也就是设置 定时中断门描述符的段中偏移值,取定时中断处理程序地址。movw$0x8e00, %dx# edx的值将被用于设置到门描述符的高32位。edx 被设置为0x0000 8e00。
RELATED

相关推荐

基于jenkins进行定制化开发

基于jenkins进行定制化开发

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写,可在Tomcat等流行的Servlet容器中运行…

📅 2026/9/20 16:39:48
【软件】【vs】Visual Studio编译c语言程序

【软件】【vs】Visual Studio编译c语言程序

1、创建新项目2、搜索c,选择“空项目”3、输入项目名称,和项目要存放的位置:4、VisualStudio资源管理器中的源文件右键选择:添加-->新建项-->c文件(.cpp),将文件命名成.c文件即可&#xf…

📅 2026/9/20 16:41:38
DirectShow图像处理实战:从Filter Graph架构到实时边缘检测实现

DirectShow图像处理实战:从Filter Graph架构到实时边缘检测实现

1. 项目概述:为什么DirectShow在图形图像处理中依然值得深挖? 如果你在Windows平台上用Visual C搞过音视频开发,或者处理过摄像头采集、视频播放、格式转换这些活儿,那“DirectShow”这个名字对你来说肯定不陌生。它是一套微软在…

📅 2026/9/20 16:41:58
MORE NEWS

更多资讯

📰

纯 Flutter 开发生产级彩票 APP:注册签到支付预测全链路落地实践

简介:这是一套面向Flutter开发者与移动端项目实践者的生产级彩票类应用源码,聚焦福彩、体彩常规彩种的预测与数据展示,并集成注册登录、每日签到、支付流程与预测算法等完整业务模块,适合希望研究真实商业项目架构、学习跨端开发与…

📰

DeepSeek工程落地手册:从部署、工具调用到生产监控

简介:本资源是一份面向AI开发者与NLP实践者的《DeepSeek应用手册》,聚焦大模型落地中的多模态交互、私有知识库构建与推理优化等核心问题。手册系统梳理了R1/V3多模型协同工作流、联网搜索触发策略、标准化指令集(如/续写、/简化、/步骤&…

📰

零序电流保护整定计算全流程:从三序网络到三段式定值配合

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Claude Code插件体系深度解析:从claude-plugins-official到自定义技能实战

1. 从 claude-plugins-official 说起:这个仓库到底解决什么问题第一次看到claude-plugins-official这个名字,很多人会下意识以为它是某个“官方插件市场”,点进去发现其实是一堆配置文件和目录结构,然后就开始犯迷糊——这玩意儿到…

📰

Claude Code插件开发指南:从加载机制到报错排查的完整实践

1. 从"官方插件"这个词说起:它到底解决了谁的痛点第一次看到claude-plugins-official这个仓库名,我下意识以为又是一个"官方示例合集"——就是那种放几个 demo、半年不更新、README 写得比代码还长的仓库。但真正把它拉下来跑通、又…

📰

ICP、ISP、IAP一次讲透:单片机固件烧录方式全解析

1. 烧录的本质:你以为是“复制文件”,其实是在“烙”芯片1.1 从“空白芯片”说起:为什么要烧录很多刚接触单片机的人会把“烧录”理解成“把程序复制进芯片”,这个说法听着没毛病,但会带来一个认知偏差:你会…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬