从mykernel来分析linux系统的启动过程

徐晨 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000


我们本次分析一个精简过的内核代码mykernel,配合kernel3.9.4使用,该代码来自https://github.com/mengning/mykernel,源码的README中已经详细说明了如何下载源码,打补丁,编译,以及在虚拟机下运行该内核镜像的方法。源码中指出:
“您只要在mymain.c基础上继续写进程描述PCB和进程链表管理等代码,在myinterrupt.c的基础上完成进程切换代码,一个可运行的小OS kernel就完成了。”

孟老师在课程公告中对mykernel做了简明的讲解:
“理解和运行mykernel,它是提供初始化好的CPU从my_start_kernel开始执行,并提供了时钟中断机制周期性执行my_time_handler中断处理程序,执行完后中断返回总是可以回到my_start_kernel中断的位置继续执行。当然中断保存现场恢复现场的细节都处理好了,mykernel就是一个逻辑上的硬件平台,具体怎么做到的一般不必深究。”

这里主要分析一下mymain.c和myinterupt.c中的相关代码是如何在kernel启动中发挥作用的。

首先,我们从pcb.h谈起:


该头文件中定义了一个两个结构体,第一个是struct Thread,它用来存储线程的ip和sp。另外一个是PCB(进程控制块),这是操作系统中一个很重要的数据结构,所有关于进程的信息都存储在PCB中,这里代码中简化了PCB的结构,只给出了一些最基本的信息,如Pid(进程号),进程状态,程序入口地址,内核堆栈,线程信息等。

有了PCB这个数据结构,我们就可以用它来创建进程或者在进行进程间切换时保存信息。

我们再来看mymain.c文件,mykernel内核是从my_start_kernel函数开始执行的,所以我们在该函数中首先创建进程,创建进程的方法就是填充PCB的信息。


我们可以从代码中看出,这里讲PCB实现成了一个环形队列,每次创建新的进程时,都将该进程插入到队列的最后一个位置,然后将该进程指向第一个进程。创建好进程之后,该函数中最重要的一段代码出现了,该部分利用嵌入式汇编来启动0号进程。


代码首先将PCB中的sp信息放入esp寄存器,然后将ebp压栈(因为此时进程堆栈为空栈,所以压入esp相当于ebp),第三第四句我们将eip压栈然后ret(即pop eip),下一条指令就会跳转到0号进程的第一条指令开始执行,在这里就是my_process()。

my_process干了一件很简单的事情,就是循环等待并print进程id,然后观察变量my_need_sched是否为1,如果是则主动进入调度函数my_schedule开始执行。


my_schedule函数在myinterupt.c中,在分析该函数之前,我们先看一下该文件中的另一个函数,my_timer_handler。


mykernel提供了时钟中断机制,周期性执行my_time_handler中断处理程序,该函数定时观察my_need_sched是否不等于1,如果是则将其置为1,使myprocess执行my_schedule()。

这时我们分析一下my_schedule,该函数在PCB环形队列中选择下一个进程进行执行,但对于处于不同状态的进程,调度方式略有不同,如果即将上CPU的进程之前已经运行过(即state为0),我们保存当前进程的信息,然后把下一个进程的信息写入到寄存器中,执行ret使下一个进程开始执行。


之前没有在运行态的(state不为0),我们先将其设置为运行态,我们这里需要初始化其ebp,因为该进程的堆栈是空栈esp=ebp。


至此,我们的mini kernel的运行分析完毕。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高斯过程回归(Gaussian Process Regression,GPR)是一种基于贝叶斯推断的回归方法,它可以用于对任意维度的函数进行建模,且具有不确定性估计的能力。R语言中有许多包可以用于实现高斯过程回归,这里介绍一下“kergp”包的使用方法。 首先需要安装并加载kergp包: ``` install.packages("kergp") library(kergp) ``` 然后,我们需要定义一个高斯过程的核函数,这里以RBF核函数为例: ``` mykernel <- k_RBF(sigma=1, ell=1) ``` 其中,sigma和ell分别是RBF核函数的两个参数。 接下来,我们需要准备训练数据和测试数据。这里以一维输入和一维输出为例: ``` x_train <- seq(0, 10, by=0.1) y_train <- sin(x_train) + rnorm(length(x_train), sd=0.1) x_test <- seq(0, 10, by=0.05) ``` 其中,训练数据x_train和y_train是在[0,10]范围内均匀采样得到的一些点,y_train是在这些点上对sin函数加上一些噪声得到的输出。测试数据x_test是在同样范围内均匀采样得到的一些点。 接下来,我们可以使用kergp包中的gpr函数进行高斯过程回归: ``` gpr_res <- gpr(x=x_train, y=y_train, kernel=mykernel, xnew=x_test) ``` 其中,x表示训练数据的输入,y表示训练数据的输出,kernel表示核函数,xnew表示测试数据的输入。 最后,我们可以通过gpr_res对象得到预测值和不确定性估计: ``` y_pred <- gpr_res$mean y_sd <- sqrt(gpr_res$var) ``` 以上就是一个简单的R语言高斯过程回归代码示例。如果您还有其他问题或者需要更详细的解释,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值