20169217 《Linux内核原理与分析》第七周作业

  首先完善一下上周的作业,上周的嵌入式汇编并没有编译成功,究其原因,还是我对传参理解不到位,write函数的3个参数都要传递才行,并不是只传谣打印的字符串就行。

  在老师的指导下并且参考了毛卫华同学的代码之后,终于编译成功啦!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    char* msg = "liuhongyi20169217";
    int len = 17;
    int result = 0;

    asm volatile (
                 "mov %2, %%edx;

" /*传入参数:要显示的字符串长度*/
                 "mov %1, %%ecx;

" /*传入参赛:文件描述符(stdout)*/
                 "mov $1, %%ebx;

" /*传入参数:要显示的字符串*/
                 "mov $4, %%eax;

" /*系统调用号:4 sys_write*/
                 "int  $0x80" /*触发系统调用中断*/
                 :"=m"(result) /*输出部分:本例并未使用*/
                 :"m"(msg),"r"(len)  /*输入部分:绑定字符串和字符串长度变量*/
                 :"%eax"); 
        
    return 0;
}

    下面我们就基于上周完成的嵌入式汇编的代码完成本周的实验。

    首先根据mooc的课程的要求执行实验第一部分:

   

    1.更新menu代码到最新版。

cd LinuxKernel
rm menu -rf
git clone https://github.com/mengning/menu.git
cd menu

    2.在main函数中增加menuconfig。

    3.增加对应的write和writeasm函数。

    基于上节课调用函数的代码,编写代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int writetext() {
    write(1,"liuhongyi20169217",17);
    return 0;
}

int writeasm() {
   char* msg = "liuhongyi20169217";
    int len = 17;
    int result = 0;

    asm volatile (
                 "mov %2, %%edx;

" /*传入参数:要显示的字符串长度*/
                 "mov %1, %%ecx;

" /*传入参赛:文件描述符(stdout)*/
                 "mov $1, %%ebx;

" /*传入参数:要显示的字符串*/
                 "mov $4, %%eax;

" /*系统调用号:4 sys_write*/
                 "int  $0x80" /*触发系统调用中断*/
                 :"=m"(result) /*输出部分:本例并未使用*/
                 :"m"(msg),"r"(len)  /*输入部分:绑定字符串和字符串长度变量*/
                 :"%eax"); 
        
    return 0;
}

int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);

    MenuConfig("writetext","writetext",writetext);
    MenuConfig("writeasm","write(asm)",writeasm);
    ExecuteMenu();
}

    4.重新编译

$ make rootfs

    实验的第一部分就完成了,现在进行实验的第二部分。

    使用qemu命令重新启动内核并使用-s和-S参数,命令如下:

$ cd /home/shiyanlou/LinuxKernel
$ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

   

    此时使用gdb进行调试,重新开一个窗口,并且输入如下命令:

$ gdb
(gdb) file linux-3.18.6/vmlinux
(gdb) target remote:1234
(gdb) continue

   系统调用流程图如下:  

     

遇到问题:

    本次实验从一开始就遇到比较棘手的问题,那就是无法搭建实验环境。无论是用自己的虚拟机还是用实验楼的虚拟实验环境,都无法从实验给的链接中更新git,所以导致后续的实验无法顺利完成,但是我根据mooc上讲的内容,将实验步骤列了出来。解决方案目前还没有,希望老师给予指导。

    书上内容总结:

    教材内容第9,10章主要介绍了同步和并发的概念和Linux解决同步和并发的方案,即锁和原子操作。

    1.最简单的确保同步的方法,原子操作。我的理解就是将数据的读写和对数据的操作捆绑到一起执行,在这个过程中不能被打断,这样便可以保证同步。

    2.介绍了解决并发执行的机制,锁。并讨论了多种锁机制,内核中最普通的锁是自旋锁,轻量级单独持有者的锁是争用时忙,还有睡眠锁mutex。我对于锁机制的理解是党多个线程抢占同一资源时,需要先行进入的的线程对资源进行锁定,待执行完成后,再释放资源给其他线程。

原文地址:https://www.cnblogs.com/dkyliuhongyi/p/6019972.html