当前课程知识点:操作系统 > 第十二讲 进程控制 > 12.3 进程加载 > 12.3 进程加载
接下来我们介绍进程加载
进程加载是指我们用户的应用程序
通过系统调用exec()加载
来完成一个新的可执行文件的加载
那在这里头呢
我们前面已经在介绍fork的时候
已经说过它的使用
用exec()这个系统调用
就可以加载一个新的可执行文件
到内存当中覆盖原来的
那个当前进程的地址空间
然后开始执行
那在这儿呢我们会来说
这个加载到底它在怎么做
那我们还知道
大家在系统加载的时候是啥样
我们CPU加电
加电之后去起动从BIOS里的程序
BIOS里的程序运行之后
就从硬盘上去加载引导扇区
引导扇区加载完了之后
是我的bootloader
bootloader然后再到我的内核映像
内核做了一系列工作之后
现在到我们的应用程序这个地方
那用户要想通过exec()
加载一个可执行程序
它类似于我们前面的
这种系统加载一样的
我把一个映像加载到内存当中
然后我得跳过去到指定的位置来执行
实际上这些呢中间就是有
关于可执行文件格式的识别的问题
不同的系统呢它可以加载的
可执行文件的格式是不一样的
这是我们首先要说的
然后再由这里头我们加载的时候
用户需要指定加载时候的参数
你比如说在我们exec()里头
要指定你后面有几个参数
然后每个参数分别是什么
好指定完了之后那这样的话
如果成功
加载成功了
那这时候呢它是相同的
跟加载之前是相同一个进程
ID是一样的
但是它执行了完全不同的程序
那这时候你的代码 堆栈 堆 数据等等
完全都被重写了
这是程序加载的过程
那在这里头实现这个加载的功能呢
相对来说也比较单一
也就是说我从外存上
把可执行文件加载进来
并且跳转到上面去执行就可以了
这和我们引导扇区不一样
引导扇区我读一块内容放那儿去
我对它的格式是没有任何理解的
但是我们现在
到执行一个应用程序的时候
你里头那可执行文件的格式
是非常复杂的
所以在这里呢主要的工作就是
你可执行文件格式的识别
那具体说起来呢在这儿呢
分成三个主要的函数
一个是sys_exec
一个是do_execve
一个是load_icode
那第一个呢
实际上是我在这里获取相应的参数
核心加载功能是在这里头
而在这里头呢最核心的部分呢
是load_icode这实际上是
识别你的可执行文件的格式
并且把它加载到
在内存里加载相应对应的段
然后开始执行
那在ucore里呢
有一个sys_exec()这样一个内核函数
它完成的呢
就是获取我们创建进程的参数
然后到这边呢它获取这些参数之后
最后调到的结果
我们可以从这儿可以看到do exec()
这是内核关于
进程加载执行的最主要的函数
在这个函数里头呢
它主要要做的工作呢
是在这里创建新进程所需要的
内存的相关的这些段结构
比如在这儿
这个地方是打开文件
读你ELF文件的内容
进来进行相应的创建
然后下面这地方呢
是它所需要的内存地址空间的
映射的创建 mm_create()
然后这地方是设置页表的基址
然后这是我们刚才在那里看到的
load_icode()这个函数
这个函数在我们这里呢
主要是解析相应的
可执行文件的格式
我们可以看到它在这里头的控制流图
那在这里头呢
它最主要的一个部分就是去读文件
那这是它最主要的操作
然后更具体的相关的实现呢
希望大家下去之后
利用这些工具可以很方便的看到
好在加载完了之后呢
那我们程序就开始执行了
实际上我们在前面讲创建的时候
也已经说过了
我的系统里的第一个线程
是在那个proc_init()里头来进行的
proc_init()那在这里呢
它手工的构造出一个进程控制块
然后把它放到就绪队列里头
然后开始执行
这时候它起动的第一个用户态的程序
就是这个init_main()
在这里头呢做了
我们下面会去走的shell的程序
那在这里头具体的执行过程呢
我们通过相应的实际代码阅读来完成
接下来我们说ucore创建的第一个进程
创建进程的函数呢
是我们这里的proc_init()
在这个函数里头呢
我们刚才已经从kern_init()里头
看到过这个函数
它完成两个内核线程的创建
idleproc()initproc()
那在这儿呢我们可以通过
它的流程图来给出一个简要的
这是proc_init()的流程图
好那在这里头我们看到
它创建第一个标志性的操作呢
是在这儿idleproc()
在这里给它复制相应的状态信息
这是利用alloc_proc()来创建
idleproc的进程控制块数据结构
然后下边这边呢就是initproc
这是在这里呢
用这里头kernel_thread()这个函数
来创建一个内核线程
执行的函数是init _main
这个内核线程创建完毕之后呢
它被赋值通过ID找
赋值然后确认它就是initproc
这是我们要找到的创建的第二个函数
然后在这个init _main这个函数里
它做了一些什么呢
实际上它这里
又创建了两个内核线程
那这两个内核线程
从这儿呢我们可以很清楚地看到
这是第一个
然后这是第二个
-0.1 Piazza讨论区
--html
-0.2 在线实验平台
--实验平台使用帮助
--平台使用帮助
-0.2在线实验平台
--Raw HTML
-1.1 课程概述
--视频
-第一讲 操作系统概述--练习
-1.2 教学安排
--视频
-1.3 什么是操作系统
--Video
-1.4 为什么学习操作系统,如何学习操作系统
--Video
-1.5 操作系统实例
--视频
-1.6 操作系统的演变
--视频
-1.7 操作系统结构
--视频
-2.1 前言和国内外现状
-2.2 OS实验目标
-2.3 8个OS实验概述
-2.4 实验环境搭建
-2.5 x86-32硬件介绍
-2.6 ucore部分编程技巧
-2.7 演示实验操作过程
--Q6
--Q7
--Q10
-3.1 BIOS
--3.1 BIOS
-3.2 系统启动流程
-3.3 中断、异常和系统调用比较
-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较
-3.4 系统调用
--3.4 系统调用
-第三讲 启动、中断、异常和系统调用--3.4 系统调用
-3.5 系统调用示例
-3.6 ucore+系统调用代码
-4.1 启动顺序
--4.1 启动顺序
-4.2 C函数调用的实现
-4.3 GCC内联汇编
-4.4 x86中断处理过程
-4.5 练习一
--4.5 练习一
-4.6 练习二
--4.6 练习二
-4.7 练习三
--4.7 练习三
-4.8 练习四 练习五
-4.9 练习六
--4.9 练习六
-5.1 计算机体系结构和内存层次
-5.2 地址空间和地址生成
-5.3 连续内存分配
-5.4 碎片整理
--5.4 碎片整理
-5.5 伙伴系统
--5.5 伙伴系统
-第五讲 物理内存管理: 连续内存分配--5.6 练习
-6.1 非连续内存分配的需求背景
-6.2 段式存储管理
-- 6.2 段式存储管理
-6.3 页式存储管理
-6.4 页表概述
--6.4 页表概述
-6.5 快表和多级页表
-6.6 反置页表
--6.6 反置页表
-6.7 段页式存储管理
-第六讲 物理内存管理: 非连续内存分配--6.8 练习
-7.1 了解x86保护模式中的特权级
-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级
-7.2 了解特权级切换过程
-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程
-7.3 了解段/页表
-第七讲 实验二 物理内存管理--7.3 了解段/页表
-7.4 了解UCORE建立段/页表
-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表
-7.5 演示lab2实验环节
-8.1 虚拟存储的需求背景
-8.2 覆盖和交换
-8.3 局部性原理
-8.4 虚拟存储概念
-8.5 虚拟页式存储
-8.6 缺页异常
--8.6 缺页异常
-9.1 页面置换算法的概念
-9.2 最优算法、先进先出算法和最近最久未使用算法
-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法
-9.3 时钟置换算法和最不常用算法
-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法
-9.4 Belady现象和局部置换算法比较
-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较
-9.5 工作集置换算法
-第九讲 页面置换算法--9.5 工作集置换算法
-9.6 缺页率置换算法
-第九讲 页面置换算法--9.6 缺页率置换算法
-9.7 抖动和负载控制
-10.1 实验目标:虚存管理
-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理
-10.2 回顾历史和了解当下
-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下
-10.3 处理流程、关键数据结构和功能
-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能
-10.4 页访问异常
-第十讲 实验三 虚拟内存管理--10.4 页访问异常
-10.5 页换入换出机制
-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制
-11.1 进程的概念
-第十一讲 进程和线程--11.1 进程的概念
-11.2 进程控制块
-第十一讲 进程和线程--11.2 进程控制块
-11.3 进程状态
-第十一讲 进程和线程--11.3 进程状态
-11.4 三状态进程模型
-11.5 挂起进程模型
-第十一讲 进程和线程--11.5 挂起进程模型
-11.6 线程的概念
-第十一讲 进程和线程--11.6 线程的概念
-11.7 用户线程
-第十一讲 进程和线程--11.7 用户线程
-11.8 内核线程
-第十一讲 进程和线程--11.8 内核线程
-12.1 进程切换
-第十二讲 进程控制--12.1 进程切换
-12.2 进程创建
-第十二讲 进程控制--12.2 进程创建
-12.3 进程加载
-第十二讲 进程控制--12.3 进程加载
-12.4 进程等待与退出
-第十二讲 进程控制--12.4 进程等待与退出
-13.1 总体介绍
-13.2 关键数据结构
-13.3 执行流程
-13.4 实际操作
-14.1 总体介绍
-14.2 进程的内存布局
-14.3 执行ELF格式的二进制代码-do_execve的实现
--14.3 执行ELF格式的二进制代码-do_execve的实现
-14.4 执行ELF格式的二进制代码-load_icode的实现
--14.4 执行ELF格式的二进制代码-load_icode的实现
-14.5 进程复制
-14.6 内存管理的copy-on-write机制
-15.1 处理机调度概念
-第十五讲 处理机调度--15.1 处理机调度概念
-15.2 调度准则
-15.3 先来先服务、短进程优先和最高响应比优先调度算法
--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc
-15.5 实时调度和多处理器调度
-第十五讲 处理机调度--15.5 实时调度和多处理器调度
-15.6 优先级反置
-第十五讲 处理机调度--15.6 优先级反置
-16.1 总体介绍和调度过程
-16.2 调度算法支撑框架
-16.3 时间片轮转调度算法
-16.4 Stride调度算法
-17.1 背景
--17.1 背景
-17.2 现实生活中的同步问题
-第十七讲 同步互斥--17.2 现实生活中的同步问题
-17.3 临界区和禁用硬件中断同步方法
-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法
-17.4 基于软件的同步方法
-第十七讲 同步互斥--17.4 基于软件的同步方法
-17.5 高级抽象的同步方法
-第十七讲 同步互斥--17.5 高级抽象的同步方法
-18.1 信号量
--18.1 信号量
-第十八讲 信号量与管程--18.1 信号量
-18.2 信号量使用
-第十八讲 信号量与管程--18.2 信号量使用
-18.3 管程
--18.3 管程
-第十八讲 信号量与管程--18.3 管程
-18.4 哲学家就餐问题
-18.5 读者-写者问题
-19.1 总体介绍
-19.2 底层支撑
-第十九讲 实验七 同步互斥--19.2 底层支撑
-19.3 信号量设计实现
-第十九讲 实验七 同步互斥--19.3 信号量设计实现
-19.4 管程和条件变量设计实现
-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现
-19.5 哲学家就餐问题
-20.1 死锁概念
-第二十讲 死锁和进程通信--20.1 死锁概念
-20.2 死锁处理方法
-第二十讲 死锁和进程通信--20.2 死锁处理方法
-20.3 银行家算法
-第二十讲 死锁和进程通信--20.3 银行家算法
-20.4 死锁检测
-第二十讲 死锁和进程通信--20.4 死锁检测
-20.5 进程通信概念
-第二十讲 死锁和进程通信--20.5 进程通信概念
-20.6 信号和管道
-第二十讲 死锁和进程通信--20.6 信号和管道
-20.7 消息队列和共享内存
-第二十讲 死锁和进程通信--20.7 消息队列和共享内存
-21.1 文件系统和文件
-第二十一讲 文件系统--21.1 文件系统和文件
-21.2 文件描述符
-第二十一讲 文件系统--21.2 文件描述符
-21.3 目录、文件别名和文件系统种类
-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类
-21.4 虚拟文件系统
-第二十一讲 文件系统--21.4 虚拟文件系统
-21.5 文件缓存和打开文件
-第二十一讲 文件系统--21.5 文件缓存和打开文件
-21.6 文件分配
-第二十一讲 文件系统--21.6 文件分配
-21.7 空闲空间管理和冗余磁盘阵列RAID
-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID
-22.1 总体介绍
-第二十二讲 实验八 文件系统--22.1 总体介绍
-22.2 ucore 文件系统架构
-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构
-22.3 Simple File System分析
-第二十二讲 实验八 文件系统--22.3 Simple File System分析
-22.4 Virtual File System分析
-第二十二讲 实验八 文件系统--22.4 Virtual File System分
-22.5 I/O设备接口分析
-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析
-22.6 执行流程分析
-23.1 I/O特点
--视频
-第二十三讲 I/O子系统--23.1 I/O特点
-23.2 I/O结构
--816C80A0F5E3B8809C33DC5901307461
-第二十三讲 I/O子系统--23.2 I/O结构
-23.3 I/O数据传输
--C58221E14388B9DB9C33DC5901307461
-第二十三讲 I/O子系统--23.3 I/O数据传输
-23.4 磁盘调度
--567A3F1FCBFB3F4C9C33DC5901307461
-第二十三讲 I/O子系统--23.4 磁盘调度
-23.5 磁盘缓存
--C327536B80D25CE79C33DC5901307461
-第二十三讲 I/O子系统--23.5 磁盘缓存
-html
--html