JOS学习笔记(九)

JOS学习笔记(一) 起初 神创造天地。  地是空虚混沌.渊面黑暗. BIOS运行在水面上。  神说、要有mbr、就加载了mbr。  神看mbr是好的、就用mbr加载了kernel。  神称mbr为引导程序、称kernel为内核.有晚上、有早晨、这是头一日。 用课余时间重新拾起JOS,作为一个码农通过了解不同技术层面的机制对自己的技术水平提高非常大,而JOS作为一个MIT的开放课程,可让我们从 阅读详情

LAB3代码已经上传。

最近忙于打WOWTCG,早就做完了一直没腾出时间写博客。

LAB3第二部分主要是处理系统调用。

第一部分我们已经让第一个env运行了起来,接着这个env执行一个cprintf,这个cprintf是一个系统调用,因为os暂时没有实现系统调用,所以系统崩溃。

在lab2我们就要完成各种系统调用以及exception和trap等的实现。

handout地址:http://pdos.csail.mit.edu/6.828/2011/lec/x86_idt.pdf

博文中的很多说明都引用了handout里面的图。

一、原理

系统调用、中断以及异常os的处理方式都一样,他们的区别只在于陷入内核的方法不同。

interrupt和exception略有差异,但总体可以认为是某些硬件机制导致我们陷入内核,而系统调用是我们在用户态程序中执行int48进行调用,用户态的调用工作在lib下的syscall.c中。之所以是int 48,是因为T_SYSCALL常量定义为48,理论上定义32--255之间的任何值都可以,0--31规系统使用。详细信息可见handout。

下面详细分析系统调用陷入内核的过程。

首先系统调用的入口在lib下的syscall.c,可以看到,函数syscall使用了嵌入式汇编,先将各个参数分别赋值给eax,ebx,ecx,edx,edi,esi,然后约定将返回值放入eax中(把返回值放入eax的过程是我们需要在内核中实现的),接着使用int 48陷入内核。

剩下的部分中断、异常、陷阱、系统调用都一样(虽然我也分不太清这几个概念),因此下文中除非特殊说明,“中断”一词代表着中断、异常、陷阱、系统调用这4个概念,但唯独中断号和系统调用号进行区分,中断号是指idt表中的索引,系统调用号是指不同的系统调用函数的标识符。

int指令是一个较为复杂的指令,其做了很多事情,按顺序包括以下几步:

1、查找idtr里面的idt地址,根据这个地址找到idt,然后根据idt找到中断向量的表项。

2、检查cpl和表项的dpl,如果cpl>dpl产生保护异常,否则继续

3、根据tssr寄存器里的tss地址找到tss在内存中的位置,读取其中的ss和esp并装载(tss结构是x86定义好的,其内存中存放的位置需要os去决定,并对其中内容的赋值也要os实现,这部分内容在trap.c的trapinitpercpu函数中,同时还包括着加载idt的逻辑)。

4、如果是一个用户态到内核态的陷入操作,则像堆栈中压入ss和esp,注意这个ss和esp是之前用户态的数据,而不是新装载的数据

5、压入esp,eflags,eip

6、修改eflags中的某些位(比如关中断)

7、如果有必要,压入errorcode,某些中断需要errorcode以及不同中断的errorcode含义可查看handout。

8、根据idt表项设置cs和eip,也就是跳转到处理函数执行。idt内容相关可查看handout。

压入后的堆栈就应该是这个样子的,跳转到相应中断处理函数的时候我们面对的就是这样一个堆栈。接着中断处理函数处理相应操作,然后根据目前堆栈里有的内容和当前寄存器的内容恢复现场,继续程序执行。

 

 

二、实验

大概弄懂了原理,接下来解析具体的实验。

1、完成trapentry.S和trap.c的部分内容,使之能正确的调用trap函数,并将一个正确的trapframe结构指针当做函数的参数

在这个实验时,还需要完成很多操作才能进行系统调用。因为加载idt的工作JOS已经帮我们做了,我们需要做的就是初始化idt,给不同的中断分配不同的处理函数。

简单分析JOS的逻辑可知,JOS是先将所有中断都跳转到trap函数,再在trap函数里调用trap_dispatch来进行分发,再在trap_dispatch中调用具体的处理函数,虽然这个过程复杂繁琐且个人认为完全没有必要,但至少这意味着idt里指向的函数只需要调用trap函数就可以了。

在trapentry.S中,根据定义的两个宏,参考handout里面errorcode所对应的中断号,可以为不同的中断号定义处理函数,名字随便取,然后再在trap.c中声明这些函数,并获取函数地址填充进idt中(使用setgate宏,使用GD_KT段,也就是OS的代码段),DPL我参考了linux一些信息,将breakpoint,overflow,以及system call设置为3,其余都是0。

此时idt初始化代码就完成了,发现所有中断处理函数跳转到_alltrap处,在trapentry.S中定义_alltrap符号,接着往堆栈里压入某些值,使堆栈看起来像是一个trapframe,此时堆栈栈顶的指针就是指向这个trapframe的指针(结构体内存从低向高增长),将这个指针也就是esp压入堆栈,调用trap函数,进入函数时,会取栈顶元素当做参数,正好就是这个trapframe,这样就完成了我们想要的功能。

接下来考虑如何压栈才能让堆栈看起来像trapframe。

tramframe看起来应该是这个样子的:

在每一个中断处理函数里,已经压入了trapno,所以在_alltrap处,还需要压入trapno以下的所有内容。接着根据要求加载内核数据段,最后再压入esp,执行call trap即可转入c执行。至此exercise 4完成。

 

2、完成部分trap_dispatch逻辑

这部分没啥可说的,根据中断号把page fault分发到trap.c里的trap_fault_handler函数,然后发现函数里把这个唯一的env给毁掉了,也就是说用户程序出了page fault直接销毁,大概是这么个逻辑。这样exercise 5就完成了。

 

3、完成breakpoint的中断处理

自己建个函数,然后在trap_dispatch里根据中断号跳转到此函数,在此函数中调用monitor(tf)即可,如果想让到达断点的程序继续执行,可在monitor中多加个命令,退出monitor中的那个死循环,然后trap函数就会根据trapframe里的内容恢复现场继续执行下去。

编程5年总算是知道这个断点是怎么实现的了,囧。

 

4、完成内核区的系统调用

根据trapframe内的系统调用号(放在eax里)完成相应的系统调用,返回结果要放在eax里,这样经过iret返回时才能得到正确的结果。

 

5、完成libmain

在libmain用刚才写好的系统调用取得该env的envid,然后根据envid得到Env结构(使用ENVX宏获取UENVS数组的索引),简单的很,也没啥可说的。

 

6、如果在内核态发生page fault,则panic

在page_fault_handler中判断是否在内核态产生page_fault,判断的方法是查看传入trapframe的cs中的DPL,如果是0,即为内核态。

 

7、系统调用中的参数检查

在系统调用中有一个是向控制台输出信息的函数sys_cputs,在此函数中要去检查用户传入的字符串所处的内存是否有映射以及是否有read权限,方法也很简单,遍历page table,查看其页表项的PTE_P和PTE_U位即可,如果通不过检测,就把这个envpanic掉。

 

好了,到此为止应该能通过绝大多数testcase,只有一个testbss除外。

bss里存放着未初始化的变量,和data段不同的是,data段存放变量及其值,而bss段只存放变量及其所占空间大小的信息,所以bss段在elf中所占用的空间要小的多。

现在的问题是,在load_icode时,我们并没有加载bss段。通过objdump来看,按JOS的逻辑,让我们在program header表中只加载ELF_PROG_LOAD类型的段是不会加载bss段的,bss段存放于elf的section表中,且其类型的id是8,因此我们必须写点代码把这个bss段加入内存才行。

但问题是实验中并没有给出这些内容相关的提示,或许是我阅读的材料不够(我没阅读所有相关材料),也许是实验的设计者压根就忘了,反正加载bss段之后就能通过测试了。

代码以上传,因版面问题,就不贴在这里了。

 

操作系统内核的绝佳学习材料——JOS 操作系统内核的绝佳学习材料——JOS 前言:关于JOS和一些经验之谈 这一学期的操作系统课使用的是MIT用于教学的JOS操作系统,并且StonyBrook在其基础上做了大量改动,最重要的变化就是从32位移植到了64位。因为个人之前曾系统学习过Linux 0.11内核(《操作系统内核Hack:(四)内核雏形》,实现到时钟中断部分停下了),深知自己从零开始实现内核的工作量。即便是如我个人实 阅读详情

相关推荐

6.828 JOS在Mac下的环境配置

官网上是建议只安装qemu的依赖,再安装他们自己改良过的qemu。但是在实际操作中configure的时候总是提示pkg_config找不到,看了下脚本好像是找不到pkg_config_exe不知道啥情况。最后参考这篇文章进行的配置 安装qemu brew install qemu 安装i386-jos-elf-gcc和i386-jos-elf-gdb brew tap liudangy...

努力学习的姜饼 1806

[学习总结]自制简易操作系统

Linux中90%以上的代码都是用在资源管理、策略、算法及数据结构等方面。操作系统受制于硬件的支持, 很大程度上它的能力取决于硬件的能力,很多操作都是硬件自动完成的。比如,处理器进入0特权级时, 会自动在任务状态段TSS中获得0特权级的栈地址。因此,要想全面理解操作系统,不仅需要了解上层软件的算法、原理、实现, 还要了解很多硬件底层的内容。 本项目实现的mini操作系统,包含: ...

trb331617的博客 5283

MIT JOS LAB3学习笔记

LAB3概述:本次操作系统实验,我们对计算机的操作系统进行了初步的探究,通过完成作业和问题,对lab3部分有了较好的理解。Lab3主要实现能运行被保护的用户模式环境(protected user-mode environment,即process)的内核服务。我们将增加数据结构来记录进程、创建进程、为其装载一个程序镜像。我们还要让JOS 内核能够处理进程产生的系统调用和异常。具体来说:第一部分主要...

codes_first的博客 1325

自制操作系统 1 准备工作

最终我们的文件中需要有如下文件。前两个是终端自然不必多说。;hello-os;TAB=4指明程序的装在位置;以下的计述用于标准FAT12格式的软盘JMP entryDB 0x90启动区的名称可以是任意字符串(8字节)DW 512;每个扇区的大小(必须为512字节)DB 1;簇的大小(必须为一个扇区)DW 1;FAT的起始位置(一般从第一个扇区开始)DB 2;FAT的个数(必须为2)DW 224;根目录的大小(一般设成224项)DW 2880;

农夫果园好好喝的博客 1796

MIT 6.828 JOS 环境配置

MIT 6.828 JOS Lab1 记录这学期刚好在学操作系统课程,课余时间也比较充足,所以着手开始做鼎鼎大名的MIT 6.828 操作系统课程的Lab。It must be a long journey, and it just started!环境搭建GIT from MIT由于是第一个Lab,我们还是先要提前准备一些东西的。这门课程的资料可以通过Git获得,具体方法如下:athena% mk

Poundssss的博客 6624

MIT6.828课程JOS在macOS下的环境配置

本文将介绍如何在macOS下配置MIT6.828 JOS实验的环境。

He11o_Liu的专栏 3845

不需要学编程,自制自己的操作系统!一个0基础自制操作系统的软件!详细教程!

​ 不需要学编程,自制自己的操作系统!一个0基础自制操作系统的软件!详细教程一、下载或python运行不会编程的可以在自制操作系统.exe免费下载,直接跳到第二点创建.py文件,内容如下

linhhanpy的博客 3160

Super4PCS文章阅读笔记

Super4PCS阅读笔记 Super4PCS阅读笔记 前言 前言 今天给大家分享一下点云配准四点法4PCS0的变种——Super4PCS。此算法的原文在:Super4PCS: Fast Global Pointcloud Registration via Smart Indexing。稍微我也会写一篇关于如何使用这篇文章的里所提供的代码进行点云粗配准。关于四点法...

Vodake的博客 4539

如何自制操作系统

以上只是非常简化的步骤,实际上,自制操作系统的开发需要对计算机底层原理和相关技术有深入的理解和掌握。它是一项复杂且耗时的任务,可能需要较长时间进行学习和研究。2. 编写引导扇区(Bootloader):操作系统的启动过程通常从引导扇区开始,引导扇区是一个512字节的容量,负责将控制权传递给操作系统的核心部分。5. 开发系统调用接口:系统调用是用户层和内核层的接口,允许用户程序通过预定义的接口调用操作系统内核提供的功能和服务。8. 进行测试和调试:对自制操作系统进行严格的测试和调试,修复存在的问题和错误。

emptyset的博客 698

CISSP背书三次失败后的终极解决方案

本文分享了作者CISSP认证三次线上背书审核失败的经历与终极解决方案。针对(ISC)²官方审核的严格性,文章详细剖析了使用公积金证明、工作证明盖章签字等常见材料的误区,并最终提出了通过构建“官方邮件往来”证据链的核心策略,以动态、可验证的方式成功通过审核,为后来者提供了详实的避坑指南和实操清单。

weixin_29219539的博客 154

别再纠结高侧低侧了!用INA199/INA219这类集成电流检测芯片,5分钟搞定精准电流测量

本文详细解析了使用INA199/INA219等集成电流检测芯片实现精准电流测量的高效方案。通过对比传统分立元件方案,突出集成芯片在精度、温度稳定性和设计简化方面的优势,并提供硬件设计避坑指南和软件实现最佳实践,帮助开发者快速掌握电流检测技术。

weixin_42685438的博客 471

《30天自制操作系统》从入门到放弃

30天自制操作系统 01day 1.0写在前面的话 关于01day~03day,可以完全参考下述链接(下述内容部分也是来源此链接): https://www.cnblogs.com/yucloud/category/1472969.html 1.1手打img 在下面这条链接中下载填制编辑软件 https://www.jb51.net/softs/601421.html#downintro2 (其实我不并推荐这种编辑器,使用vscode即可:https://www.cnblogs.com/baby123/p/

wxkhturfun的博客 1万+

【PyTorch深度学习项目实战100例目录】项目详解 + 数据集 + 完整源码

大家好,我是阿光。本专栏整理了《深度学习100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。正在更新中~ ✨。

优快云 精品推荐 10万+

JOS学习笔记(三)

过了个年,好久没碰专业内的东西了,之前做的JOS相关的东西都快忘了,还是看了前面两篇日志才想起来。 当进入内核后基本都是比较简单的代码了,我也并没有全部分析,根据讲义要求只分析了一下printf函数和堆栈的backtrace,所以这篇日志也就写这两个方面吧。 1、printf函数。 进入kernel后从i386_init函数开始,首先做一些初始化工作,包括部分内存的清零,初始化显示器串口等(

锐之锋芒 4934

详细分析 Bladex中的swagger-resources资源未授权访问的解决方法

有如下方式,网关过滤、去除配置以及修改代码还有隐藏彩蛋(附Demo),推荐阅读

码农研究僧的博客 1727

YOLO26跨时代升级!YOLO26 MLCA注意力机制解读

摘要: 本文提出了一种基于多级上下文聚合(MLCA)注意力机制的改进卷积神经网络。MLCA模块通过局部和全局注意力机制动态调整特征图权重,结合了ECA注意力与自适应池化,显著提升特征表达能力。实验表明,添加MLCA后模型mAP提升12.11,准确率提高5.43。文中详细解析了MLCA1模块的工作原理,包括局部/全局池化、卷积操作和注意力加权机制,并介绍了集成MLCA的Bottleneck_MLCA模块。该机制通过多层次特征融合,在保持计算效率的同时增强模型对关键特征的敏感性。最后提供了YOLOv26-MLC

m0_71589036的博客 283

JOS学习笔记(七)

接前一篇。 上篇日志主要是完成了一些分页相关机制的工作,但还没有真正的去使用这个分页系统。Lab2的part3部分主要就是让我们使用part2中完成的映射机制来初始化内核的页目录和页表,并将此页目录加载到cr3里,让os真正去使用我们初始化之后的页目录以取代kernpgdir.c里面简单的页目录。 在开始之前让我们看一下JOS的虚拟内存分布图,在part3里的所有工作就是照着此图实现其中的部分

锐之锋芒 4388

【软件使用】向日葵网络连接错误

一直报这个错误,尝试了修改版本无果,各种密码都正确,最后得出结轮是时间没有同步,查看代理是否更改了时间,做一下同步即可。

andeyeluguo的博客 7974

JOS学习笔记(十一)

JOS LAB4 PART A的剩余部分

锐之锋芒 5333

【二】MADDPG多智能体算法实现(parl)【追逐游戏复现】

论文全称:Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments 论文原文:https://download.youkuaiyun.com/download/sinat_39620217/16203960 论文翻译:https://blog.youkuaiyun.com/qiusuoxiaozi/article/details/79066612 ...

丨汀、的博客 2万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

JOS学习笔记(五)

神说、内存之间要有映射、将地址空间分为虚实。  神就造出两级页表、将变换前的地址、变换后的地址分开了.事就这样成了。  有晚上、有早晨、是第二日。 来到了lab2,内存管理,该实验分为两部分,第一部分为物理内存管理,第二部分为虚拟内存管理,本篇先描述lab1。 做本章实验一定头脑中要时刻清晰的记住两个内存分布图:物理内存分布图以及虚拟内存分布图。 物理内存的分布在前面的笔记中有介

锐之锋芒 8309

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

JOS学习笔记(四)

Lab1还差最后一部分,就是给出具体的调试信息,如下面所示: K> backtrace Stack backtrace: ebp f010ff78 eip f01008ae args 00000001 f010ff8c 00000000 f0110580 00000000 kern/monitor.c:143: monitor+106 ebp f010ffd

锐之锋芒 4189

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

JOS学习笔记(八)

神说、内核要有自己的数据、使用户不可访问.事就这样成了。  神称高地址为内核空间、称低地址为用户空间. 神看着是好的。  神说、用户要有自己的进程、和自己的页表、并可以进行系统调用.事就这样成了。   有晚上、有早晨、是第三日。  1、lab3概述 lab3大体分为两部分,第一部分包括执行环境(可以简单的理解为进程,下文也用进程代替执行环境)的建立和运行第一个进程,第二个部分初始

锐之锋芒 8154

JOS学习笔记(二)

接上篇,文件跳转到了entry.S里面,这是kernel的入口。首先面临这么一个问题,kernel被加载到了什么地方? 回想上篇elf文件的加载机制,以及objdump里打印出的kernel信息,可以看到,kernel的代码段(text段)被加载到了0x100000的位置,也就是1m的位置,所以内存布局如下: +------------------+ <- 0xFFFFFFFF (4GB)

锐之锋芒 3487

MIT JOS 理解lab1

总结MIT的操作系统实验 JOS lab1,解释PC 启动的几个流程和跳转,重点在于gdt的建立,即实模式到保护模式的转换

MSRA_SE_TEAM的专栏 4165

Learning by doing——JOS lab1

JOS是MIT开放课程6.828的实验系统,它做好了涉及底层硬件的基本操作,留给我们一个OS空架子,待我们一步步添加代码,最终形成功能完善的OS。最近做完了lab1,相对于看Linux源码轻松许多,但却切实体验了一把动手写操作系统的感觉。在做实验的时候,要明白的一点是,做这个实验是为了帮助我们更好的理解操作系统的概念和基本的设计原则,多想想要是自己设计这个系统会怎么做,然后对比JOS设计,给出

自由而不散漫,主见而不偏执 1422
上一篇: JOS学习笔记(八)
下一篇: Android下网络接口能耗估计原理
ROger__Wong
博客等级 码龄14年 250粉丝 78原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值