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

告别RXTX:SpringBoot集成jSerialComm实现更现代的串口通信(附完整代码对比)

本文详细介绍了如何从传统的RXTX库迁移到jSerialComm,实现SpringBoot项目中更现代的串口通信。通过对比两种技术的依赖配置、API设计和跨平台支持,展示了jSerialComm在简化部署、提升性能和增强稳定性方面的优势,并提供了完整的代码示例和实战经验。

weixin_42522964的博客 286

如何自制操作系统

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

emptyset的博客 698

开源项目 ruoyi-sso-oauth2(一)环境配置

Ruoyi若依实现单点登录SSO、oauth2认证

Xiaoweidumpb 9684

PD虚拟机安装CentOS7后必做的Parallels Tools配置指南(附常见错误解决)

本文详细指导在Mac的Parallels Desktop虚拟机中安装CentOS 7后如何高效配置Parallels Tools,包括环境准备、镜像挂载、依赖问题解决及性能优化。特别针对常见错误如挂载失败、依赖缺失等提供实用解决方案,帮助用户实现主机与虚拟机间的无缝交互和显示优化。

weixin_29288313的博客 302

《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万+

修改Avaya IP-Office电话交换机出厂自带的提示语音内容

1,本文的应用场景是在使用Avaya IP-office 500 v2电话交换机时,来电振铃超时后,会转入语音信箱,呼叫者会听到一条语音信箱留言的欢迎辞(…请留言…)。但我们单位情况比较特殊,首先是的IPO配置很精简,内嵌的语音信箱只能保留3天,用处不大;其次是用户没有收听语音信箱的习惯;第三是我们单位使用数字中继和DID,每人一个直拨号码,不通过总机转接。很多业务是单线联系,所以一旦来电无法接通,来电者可能完全无法联系到我们单位的其他同事。出于这三点原因,我们希望将语音信箱的欢迎辞,增加告知我们的总机电话

qlin4cn的博客 4919

JOS学习笔记(三)

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

锐之锋芒 4934

Altium Designer(AD24/25)导出DXF或DWG结构文件的方法

DXF(Drawing Exchange Format)和DWG(Drawing)是两种常见的CAD(计算机辅助设计)文件格式,常用于结构和硬件之间的沟通。本文介绍Altium Designer(AD24/25)导出DXF或DWG结构文件的方法。

fydar的博客 2333

Oracle EBS GL日记账批“选定以过账”状态数据修复

日记账来源:应收账款。用户操作过账以后,自动提交请求“过账:单一分类账”一直运行中,该请求执行5,6个小时甚至10多个小时无法完成,导致“标准管理器”阻塞大量请求待定,“冲突解决管理器”的待定数量不断增加。系统管理员不得不把该请求强制取消,此时,日记账批的状态处于“选定以过账”(GL_JE_BATCHES.STATUS为S),如下图 检查此日记账批有3千多条日记账题头,由于日记账比较多,日记账的科目余额计算需要大量服务器资源和执行时间比较长。

陈显平的专栏-Oracle EBS 3245

JOS学习笔记(七)

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

锐之锋芒 4388

YOLO26训练自己的数据集,从代码下载到实例测试 (含YOLO26网络结构图)

在Windows10上配置CUDA环境教程2026年1月14日,YOLO26是最新发布的计算机视觉模型。支持多种任务,包括目标检测、实例分割、图像分类、姿态估计、有向目标检测以及物体跟踪等。以上就是YOLO26训练自己数据集的全部过程啦,欢迎大家在评论区交流~

Limiiiing的博客 6521

JOS学习笔记(十一)

JOS LAB4 PART A的剩余部分

锐之锋芒 5333

基于libVLC的视频播放器之四:直接使用libVLC

一.效果 播放本地文件 播放网络url:rtsp://3.84.6.190/vod/mp4:BigBuckBunny_115k.mov 二.实现 既然有VLC-Qt,为什么还要直接调用libVLC呢,因为直接调用会加深对整个播放流程的理解,方便后面修改VLC-Qt源码。 注意事项: 1.编译报错:error C2065: “libvlc_media_read_cb”: 未声明的标识符。修改如下: 2.libvlc_new(0, nullptr)返回null 将plugins

草上爬的博客 5049

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JOS学习笔记(五)

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

锐之锋芒 8309

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

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

IMSL CNL 7.0.0 (x86-64)Crack

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

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

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、付费专栏及课程。

余额充值