Linux内核分析——操作系统是如何工作的

姓名:王晨光

学号:20133232

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

一、进程的启动和切换源代码及分析

typedef struct PCB用于表示定义了一个进程,定义了进程管理相关的数据结构。同时也设置了用于保存EIP和ESP的数据类型。

下列代码为mymain.c部分代码:

void __init my_start_kernel(void)
{
int pid = 0;
    int i;
    task[pid].pid = pid;/*将进程号初始化为0*/
    task[pid].state = 0;
task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process;
/*把进程的入口和eip都初始化为my_process函数的入口地址*/
task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1];
/*将堆栈的栈顶地址保存为栈的最后一个元素,即最高的地址*/
task[pid].next = &task[pid];
/*next指针指向自己*/
    for(i=1;i<MAX_TASK_NUM;i++)
    {
        memcpy(&task[i],&task[0],sizeof(tPCB));
/*将task[0]的信息全部复制到各个新进程中*/
        task[i].pid = i;/*将新进程的pid设置为变量i*/
        task[i].state = -1;/*新进程的状态为unrunnable*/
        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];
    }
    /* start process 0 by task[0] */
    pid = 0;
    my_current_task = &task[pid];//将当前进程设置为0号进程
    asm volatile(
/*把0号进程的esp放入esp寄存器*/
        "movl %1,%%esp\n\t"     /* set task[pid].thread.sp to esp */
        "pushl %1\n\t"          /* push ebp */
        "pushl %0\n\t"          /* push task[pid].thread.ip */
        "ret\n\t"               /* pop task[pid].thread.ip to eip */
        "popl %%ebp\n\t"
        :
        : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)   /* input c or d mean %ecx/%edx*/
    );
}

系统总是从0号进程开始启动。以上代码完成的任务主要是初始化进程,然后开始执行第一个进程,执行完RET操作之后将会跳转到下一个函数中执行。

一下代码为myinterrupt.c部分代码:

void my_timer_handler(void)
{
#if 1
/*函数每执行1000次,并且my_need_sched不等于1的时候执行if判断,然后把my_need_sched置为1*/
    if(time_count%1000 == 0 && my_need_sched != 1)
    {
        printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");
        my_need_sched = 1;
    }
    time_count ++ ;
#endif
    return;
}
void my_schedule(void)
{
    tPCB * next;/*下一个进程*/
    tPCB * prev;/*当前进程*/

    if(my_current_task == NULL
        || my_current_task->next == NULL)
    {
        return;
    }
    printk(KERN_NOTICE ">>>my_schedule<<<\n");
/* schedule */

    next = my_current_task->next;
prev = my_current_task;
    if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */
    {
        /* switch to next process */
        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 */
            "pushl %3\n\t"
            "ret\n\t"               /* restore  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)
        );
        my_current_task = next;
        printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
    }
    else
{
        next->state = 0;
        my_current_task = next;
        printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
        /* switch to new process */
        asm volatile(
            "pushl %%ebp\n\t"       /* save ebp */
            "movl %%esp,%0\n\t"     /* save esp */
            "movl %2,%%esp\n\t"     /* restore  esp */
            "movl %2,%%ebp\n\t"     /* restore  ebp */
            "movl $1f,%1\n\t"       /* save eip */
            "pushl %3\n\t"
            "ret\n\t"               /* restore  eip */
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        );
    }
    return;
}

这段代码中,my_schedule函数是重点,它实现了时间片轮转的中断处理过程。这个函数分两次执行,第一次是0号进程跳转到1号进程,而第二次进入则是执行pop1 ebp恢复现场,然后return函数,返回到原调用者也就是0号进程的process里面。

二、实验过程

在实验楼中运用搭建好的环境打开文件

运行的程序

mymain.c程序代码

myinterrupt.c程序代码

实验总结:实验过程中源代码中的很多行代码看不懂,通过百度、观看视频有了一定的了解,也大致了解了操作系统是如何工作的。我们可以认为一个进程相当于一个堆栈,每个进程有自己的堆栈空间。如果将ebp和esp修改为另一个进程的ebp和esp,就可以完成进程的切换。当进程切换时,系统也会保存当前的工作状态,以便于下次恢复进程,使进程继续执行。

时间: 2024-10-13 09:51:42

Linux内核分析——操作系统是如何工作的的相关文章

Linux内核分析--操作系统是如何工作的

“平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 一.初始化进程 操作系统内核启动入口函数是void __init my_start_kernel(void): 在这里简单定义进程的的两个cpu状态: struct Thread {    unsigned long        ip; //表示eip指令    unsigned long        sp;/

linux内核分析--计算机是如何工作的

知识点: 冯诺依曼体系结构结构,它最核心的思想是存储程序计算机. cpu通过总线与内存连接,依靠ip指针依次从内存中取出一条指令执行. API:程序员与计算机的接口界面. ABI:程序与CPU的接口界面. 寄存器.寻址方式和各类指令在学习<深入理解计算机>和<汇编>时已做了详细了解,不再赘述. 实验: 截图入下: 原代码为: int g(int x) { return x+3; } int f(int x) { return g(x); } a int main(void) { r

Linux内核分析——计算机是如何工作的

实验楼实验截图:

linux内核分析(网课期末&amp;地面课期中)

堆栈变化过程: Linux内核分析——计算机是如何工作的 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: enter pushl %ebp movl %esp,%ebp leave movl %ebp,%esp popl %ebp 函数参数传递机制和局部变量存储 中断,多道程序操作系统的基点,

linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码

计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针  (stack pointer) Ebp 基址指针 (base pointer) 堆栈操作 Push:pop Ebp用作记录当前函数调用基址- 其他关键寄存器   中断 Call指令:1.将eip中下一条指令的地址A保存在栈顶:2.设置eip指向被调用程序代码开始处 1.Call xxx 2.进入xxx pushl %ebp mov

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

操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能: enter pushl %ebp movl %esp,%ebp leave movl %ebp,%esp popl %ebp 函数参数传递机制和局部变量存储 中断,多道程序操作系统的基点,没有中断机制程序只能

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

马启扬 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1. 小结:计算机是怎样工作的 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构. 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能.(函数参数传递

魏昊卿——《Linux内核分析》第二周作业:了解操作系统是怎样工作的

魏昊卿——<Linux内核分析>第二周作业:了解操作系统是怎样工作的 一.实验部分 使用实验楼的虚拟机打开shell cd LinuxKernel/linux-3.9.4 qemu -kernel arch/x86/boot/bzImage 然后cd mykernel 您可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c 使用自己的Linux系统环境搭建过程参见mykernel,其中也可以找到一个简单的时间片轮转多道程序内核代码 mymain.c myinterr

Linux内核分析之操作系统是如何工作的

在本周的课程中,孟老师主要讲解了操作系统是如何工作的,我根据自己的理解写了这篇博客,请各位小伙伴多多指正. 一.知识点总结 1. 三个法宝 存储程序计算机:所有计算机基础性的逻辑框架. 堆栈:高级语言的起点,函数调用需要堆栈机制. 中断机制:多道系统的基础,是计算机效率提升的关键. 2. 函数调用堆栈 堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间,即CPU内已经集成好了很多功能. 堆栈含以下元素: 函数调用框架 传递参数 保存返回地址(%eax) 提供局部变量空间 等等 C语言编译器