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

一、计算机是如何工作的

  存储程序计算机工作模型是计算机系统最基础的逻辑结构

  函数调用堆栈是高级语言得以运行的基础

  中断时多道程序操作系统的基点

二、堆栈:c语言程序运行时必须的一个记录调用路径和参数的空间

  函数调用框架

  传递参数

  保存返回地址

  提供局部变量空间

三、堆栈相关寄存器

  esp:堆栈指针

  ebp:基址地址

  堆栈操作:push:栈顶地址减少4个字节,pop:栈顶地址增加4个字节

其他关键寄存器:-cs·eip:总是指向下一条指令地址

  顺序执行:总是指向地址连续的下一条指令

  跳转/分支:call ret

四、gcc-g生成可执行文件

objdump -S得到反汇编代码

五、传递参数机制

第一句和第二句分别是把y和x的值存入堆栈

六、局部变量的存储机制

第三句是在堆栈中预留一部分空间存储局部变量。

七、借助Linux内核部分源代码模拟存储程序计算机工作模型及时钟中断

查看源代码:

每循环100000次打印一句话

每执行一次,就会有一次时钟中断。

八、c代码中嵌入汇编代码的写法

例:

汇编代码第一句中的%是转义字符

第二句中的%1是指val1,这一句就是把%1即val1的值赋给eax

“c”(val1)意思是把val1的值放入ecx寄存器。

九、一个简单的操作系统内核代码

struct Thread { 
unsigned long ip; //用于保存eip和esp
unsigned long sp;
};
typedef struct PCB{
int pid; //进程ID
volatile long state; //进程状态
char stack[KERNEL_STACK_SIZE]; //内核堆栈
/* CPU-specific state of this task */
struct Thread thread;
unsigned long task_entry; //进程入口(一般都是main函数
struct PCB *next; //进程通过链表连接
}tPCB;
tPCB task[MAX_TASK_NUM]; //声明一个task数组
tPCB * my_current_task = NULL; //当前task指针
volatile int my_need_sched = 0; //是否需要调度 void my_process(void); void __init my_start_kernel(void) //初始化
{
int pid = 0;
int i;
/* Initialize process 0*/ //当前是0号进程
task[pid].pid = pid;
task[pid].state = 0;/* -1 不可运行, 0 可运行, >0 停止*/
task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process; //进程入口
task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1]; //堆栈的栈顶位置
task[pid].next = &task[pid]; //下一个进程还是指向自己(这时候没有其他进程) /*fork more process */
for(i=1;i<MAX_TASK_NUM;i++)
{
memcpy(&task[i],&task[0],sizeof(tPCB));
task[i].pid = i;
task[i].state = -1;
task[i].thread.sp = (unsigned long)&task[i].stack[KERNEL_STACK_SIZE-1];
task[i].next = task[i-1].next;
task[i-1].next = &task[i];
} pid = 0;
my_current_task = &task[pid];
asm volatile(
"movl %1,%%esp\n\t" /* set task[pid].thread.sp to esp */ //确定esp的位置
"pushl %1\n\t" /* push ebp */ //当前的栈是空的,ebp就等于esp
"pushl %0\n\t" /* push task[pid].thread.ip */ //IP压栈
"ret\n\t" /* pop task[pid].thread.ip to eip */ //弹出来eip,这之后0号进程正式启动
"popl %%ebp\n\t" //弹出来ebp,内核初始化工作完成
:
: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp) /* input c or d mean %ecx/%edx*/
);
} void my_process(void) //所有的进程都以这个作为起点
{
int i = 0;
while(1)
{
i++;
if(i%10000000 == 0)
{
printk(KERN_NOTICE "this is process %d -\n",my_current_task->pid);
if(my_need_sched == 1) //执行10 000 000次才判断一次是否需要调度
{
my_need_sched = 0;
my_schedule();
}
printk(KERN_NOTICE "this is process %d +\n",my_current_task->pid);
}
}
}

十、两个正在运行的进程之间作进程上下文切换

asm volatile(    

 "pushl %%ebp\n\t"   /* save ebp */
"movl %%esp,%0\n\t" /* save esp */
"movl %2,%%esp\n\t" /* restore esp */
"movl $1f,%1\n\t" /* save eip */ //$1f就是指标号1:的代码在内存中存储的地址
"pushl %3\n\t"
"ret\n\t" /* restore eip */ //这两句使得下一个进程的ip作为eip,这样下一个进程就会接下来执行
"1:\t" /* next process start here */
"popl %%ebp\n\t"
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);

总结:

操作系统具有“两把剑”即中断上下文和进程上下文的切换;这样的特性使得操作系统可以具有一定的标准来选择执行和中断程序,调配资源

linux内核分析 第二周 操作系统是如何工作的的更多相关文章

  1. Linux内核分析第二周--操作系统是如何工作的

    Linux内核分析第二周--操作系统是如何工作的 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  2. 20135327郭皓——Linux内核分析第二周 操作系统是如何工作的

    操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的 ...

  3. LINUX内核分析第二周学习总结——操作系统是如何工作的

    LINUX内核分析第二周学习总结——操作系统是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  4. Linux内核设计第二周——操作系统工作原理

    Linux内核设计第二周 ——操作系统工作原理 作者:宋宸宁(20135315) 一.实验过程 图1 执行效果 从图中可以看出,每执行my_ start_ kernel函数两次或一次,my_ time ...

  5. Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码

    Linux内核分析第二周学习博客 本周,通过实现一个简单的操作系统内核,我大致了解了操作系统运行的过程. 实验主要步骤如下: 代码分析: void my_process(void) { int i = ...

  6. linux内核分析第二周

    网易云课堂linux内核分析第二周 20135103                王海宁 <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  7. Linux内核分析第二周学习笔记

    linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  8. Linux内核分析——第二周学习笔记20135308

    第二周 操作系统是如何工作的 第一节 函数调用堆栈 存储程序计算机:是所有计算机基础的框架 堆栈:计算机中基础的部分,在计算机只有机器语言.汇编语言时,就有了堆栈.堆栈机制是高级语言可以运行的基础. ...

  9. Linux内核分析第二周学习总结:操作系统是如何工作的?

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 ...

随机推荐

  1. 记Thinkpad的一次扩容升级经历

    俗话说:" 工欲善其事,必先利其器" 阅读目录: 背景 目标 准备 友情提示 制作引导盘 分区及备份 拆机装盘 重装系统 写在结束的 参考资料 背景: 作为一个近六年的IT从业Co ...

  2. js插件实现一键复制功能

    clipboard.js 可以实现纯 JS 的从浏览器复制文本到系统剪贴板的功能. 使用方法: 1. 下载 clipboard.js,并在页面中引入该插件.clipboard.js 下载地址: htt ...

  3. JUC——ThreadFactory线程工厂类(四)

    ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...

  4. Zookeeper-----Zookeeper概述

    一:Zookeeper的概念? ZooKeeper是一种分布式协调服务,用于管理大型主机.在分布式环境中协调和管理服务是一个复杂的过程.ZooKeeper通过其简单的架构和API解决了这个问题.Zoo ...

  5. JavaScript学习笔记(五)——类型、转换、相等、字符串

    第六章 类型 相等 转换等 一.类型 1 typeof(); typeof是一个内置的JavaScript运算符,可用于探测其操作数的类型. 例: <script language=" ...

  6. IT视频课程集

    马哥Linux培训视频课程:http://pan.baidu.com/s/1pJwk7dp Oracle.大数据系列课程:http://pan.baidu.com/s/1bnng3yZ 天善智能BI培 ...

  7. rest_framework组件

    认证组件 局部认证 在需要认证的视图类里加上authentication_classes = [认证组件1类名,认证组件2类名....] 示例如下: seralizers.py from rest_f ...

  8. 哈夫曼(Huffman)树+哈夫曼编码

    前天acm实验课,老师教了几种排序,抓的一套题上有一个哈夫曼树的题,正好之前离散数学也讲过哈夫曼树,这里我就结合课本,整理一篇关于哈夫曼树的博客. 主要摘自https://www.cnblogs.co ...

  9. 【并查集】 不相交集合 - 并查集 教程(文章作者:Slyar)

    最近写了一个多星期的并查集,一瞬间贴出这么多解题报告,我想关于并查集的应用先告一段落吧,先总结一下. 在网上看到一篇关于并查集比较好的教程(姑且允许我这么说吧),不转过来是在可惜.献给爱学习的你 文章 ...

  10. css3浏览器私有属性前缀使用详解

    什么是浏览器私有属性前缀 CSS3的浏览器私有属性前缀是一个浏览器生产商经常使用的一种方式.它暗示该CSS属性或规则尚未成为W3C标准的一部分. 以下是几种常用前缀 -webkit- -moz- -m ...