栈的地址编号 linux,Linux第三周作业

1.三个法宝

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

②函数调用堆栈,堆栈完成了计算机的基本功能:函数的参数传递机制和局部变量存取 ;

③中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序。

2.堆栈的基本功能:

(1)函数调用框架、传递参数(32位)、保存返回地址(如eax保存返回值/内存地址)、提供局部变量空间

(2)与堆栈相关的寄存器:esp和ebp

与堆栈相关的操作:push(入栈时esp指针会减4)、pop(出栈时esp指针会加4)

(3)CS:eip总是指向下一条指令的地址

C代码中嵌入汇编代码

一、实验要求

完成一个简单的时间片轮转多道程序内核代码,代码见视频中或从mykernel找。

详细分析该精简内核的源代码并给出实验截图,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”,博客内容的具体要求如下:

题目自拟,内容围绕操作系统是如何工作的进行;

博客中需要使用实验截图

博客内容中需要仔细分析进程的启动和进程的切换机制

总结部分需要阐明自己对“操作系统是如何工作的”理解。

二、实验过程

首先通过cd LinuxKernel/Linux-3.9.4,“cd”表示进入目录Linux-3.9.4,用rm -rf mykernel命令强力删除mykernel。使用命令patch -pl< ../mykernel_for_linux3.9.4sc.patch,patch命令用于为特定软件包打补丁,该命令使用diff命令对源文件进行操作。格式:patch [选项] [原始文件 [补丁文件]

6c1555302777729326ca3efa0910d9ec.png

在Linux系统中,专门提供了一个make命令来自动维护目标文件,与手工编译和连接相比,make命令的优点在于他只更新修改过的文件(在Linux中,一个文件被创建或更新后有一个最后修改时间,make命令就是通过这个最后修改时间来判断此文件是否被修改),(make还是不太懂)使用命令qemu -kernel arch/x86/boot/bzImage搭建目标环境

6c1555302777729326ca3efa0910d9ec.png

6c1555302777729326ca3efa0910d9ec.png

通过cd mykernel ,打开mykernel目录,用ls命令看到目录内容中包括 mymain.c ,myinterrupt.c,使用命令vi mymain.c以及vi myinterrupt.c可以看到代码

6c1555302777729326ca3efa0910d9ec.png

6c1555302777729326ca3efa0910d9ec.png

可以看到每当i增加100000会执行(printf函数输出my_ start_ kernel _ here …)时会触发一次时钟中断,在由时钟中断处理函数输出(>..>>my_timer_handler<

二 操作系统内核源代码分析

首先是mypcb.h

+#define MAX_TASK_NUM 10 // max num of task in system //进程参与内核时间片转,这个系统最多有10个进程

+#define KERNEL_STACK_SIZE 10248 //每个进程栈的大小

+#define PRIORITY_MAX 30 //priority range from 0 to 30

+

+/ CPU-specific state of this task */

+struct Thread {

unsigned longip;//point to cpu run address //用于eip的保存

unsigned longsp;//point to the thread stack's top address //用于esp的保存

//todo add other attrubte of system thread

+};

+//PCB Struct

+typedef struct PCB{ //用于表示一个进程,定义了进程管理相关的数据结构

int pid; // pcb id //进程编号

volatile long state;/* -1 unrunnable, 0 runnable, >0 stopped */

char stack[KERNEL_STACK_SIZE];// each pcb stack size is 1024*8

/* CPU-specific state of this task */

struct Thread thread;

unsigned longtask_entry;//the task execute entry memory address 进程第一次执行开始的地方

struct PCB *next;//pcb is a circular linked list //用于构造进程链表

unsigned long priority;// task priority

//todo add other attrubte of process control block

+}tPCB;

+//void my_schedule(int pid);

+void my_schedule(void); //调用了my_schedule

接下来是mymain.c

+tPCB task[MAX_TASK_NUM];

+tPCB * my_current_task = NULL;

+volatile int my_need_sched = 0; //定义一个标志,用来判断是否需要调度

+

+void my_process(void);

+unsigned long get_rand(int );

+

+void sand_priority(void)

+{

int i;

for(i=0;i

task[i].priority=get_rand(PRIORITY_MAX);

+}

+void __init my_start_kernel(void)

+{

int pid = 0; 初始化一个进程0

/* Initialize process 0*/

task[pid].pid = pid;

task[pid].state = 0;/* -1 unrunnable, 0 runnable, >0 stopped */

// set task 0 execute entry address to my_process

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(pid=1;pid

{

memcpy(&task[pid],&task[0],sizeof(tPCB));

task[pid].pid = pid;

task[pid].state = -1;

task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1];

task[pid].priority=get_rand(PRIORITY_MAX);//each time all tasks get a random priority //每个进程都有自己的堆栈,把创建好的新进程放到进程列表的尾部

}

task[MAX_TASK_NUM-1].next=&task[0];

printk(KERN_NOTICE "\n\n\n\n\n\n system begin :>>>process 0 running!!!<<

/* start process 0 by task[0] */

pid = 0;

my_current_task = &task[pid];

+asm volatile(

"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*/

+);

+}

+void my_process(void) //定义所有进程的工作,if语句表示循环1000万次才有机会判断是否需要调度。

+{

int i = 0;

while(1)

{

i++;

if(i%10000000 == 0)

{

if(my_need_sched == 1)

{

my_need_sched = 0;

sand_priority();

my_schedule();

}

}

}

+}//end of my_process

+//produce a random priority to a task

+unsigned long get_rand(max)

+{

unsigned long a;

unsigned long umax;

umax=(unsigned long)max;

get_random_bytes(&a, sizeof(unsigned long ));

a=(a+umax)%umax;

return a;

+}

来源:https://www.cnblogs.com/2017yaya/p/7675254.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 北邮linux的第三次上机作业是在系统管理课程中所进行的,主要涵盖了对Linux系统的进程管理、文件系统扩展、定时任务、用户和组管理等方面的学习。 在进程管理方面,我们主要掌握了如何使用ps命令、top命令和kill命令来查看、控制和关闭进程。在文件系统扩展方面,我们学习了如何使用LVM技术来管理硬盘的扩容和分区,以及如何使用fdisk命令来对磁盘进行分区管理。 此外,我们还掌握了如何使用crontab命令来进行定时任务的管理和设置,以及如何使用useradd命令和usermod命令来进行用户和组的管理和权限设置。这些技能对于如今的系统管理者而言是必须的。 在此次实验中,我们通过实际操作,更好地理解了Linux系统管理的机制和原理,掌握了课堂所学的知识点,并且对系统管理者所需要具备的能力进行了深入的思考和探讨。这些都是我们在今后的学习和工作中必不可少的技能。 ### 回答2: 北邮linux第三次上机作业是一项挑战性较高的任务,要求参与者具备一定的软件编程和计算机网络方面的知识。任务主要分为两个部分,第一部分是编写程序,第二部分是进行网络配置。 在编写程序的部分,参与者需要使用C或C++编写一个多线程的程序,并通过文件读取或用户输入来进行数据处理。该任务要求参与者能够熟练运用多线程的编程思想,以及能够对数据进行有效的处理和分析。此外,还要求程序能够稳定运行,并在遇到异常情况时给出正确的提示信息。 在网络配置的部分,参与者需要在Linux系统上配置一个网络服务,并对相应的服务进行测试。该任务要求参与者具备一定的计算机网络知识,能够熟练操作Linux系统,并能够利用相应的工具完成网络配置。此外,还要求参与者能够对配置的服务进行实际测试,并对测试结果进行分析。 总的来说,北邮linux第三次上机作业是一项涉及多个方面的任务,要求参与者具备综合的软件编程和计算机网络能力。完成该任务可以帮助参与者提高自己的技术水平,同时也有助于加强他们的团队沟通和协作能力。 ### 回答3: 北邮Linux第三次上机作业是一项关于Shell编程的实践任务,要求学生通过练习,掌握Shell脚本的基本语法和应用,加深理解Linux操作系统的特性和原理。该次实践作业旨在提高学生的实际操作能力,培养学生的团队精神和创新意识。 该作业的主要任务是实现一个小型的Shell应用程序,包括输入输出和文件操作、字符串操作和文件查找等多个功能。学生需要根据题目要求设计功能模块,编写Shell脚本程序,并进行测试和调试。实践过程中,要注意代码规范性和运行效率,以及对实验结果的记录和总结。 通过这次实践作业,学生可以更加深入地理解Shell编程语言,掌握Linux操作系统的基本操作和应用技巧,提高自己的逻辑思维和编程水平。同时,通过团队协作和分享经验,可以加强学生的交流和合作意识,培养创意和创业精神。 总之,北邮Linux第三次上机作业是一项富有挑战和创新性的实践任务,可以为学生打下深厚的理论和实践基础,提高学生的实际操作能力,激励学生的创新和创业精神,为未来的职业生涯做好充分准备。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值