首先完善一下上周的作业,上周的嵌入式汇编并没有编译成功,究其原因,还是我对传参理解不到位,write函数的3个参数都要传递才行,并不是只传谣打印的字符串就行。
在老师的指导下并且参考了毛卫华同学的代码之后,终于编译成功啦!
#include#include #include #include int main(){ char* msg = "liuhongyi20169217"; int len = 17; int result = 0; asm volatile ( "mov %2, %%edx;\n\r" /*传入参数:要显示的字符串长度*/ "mov %1, %%ecx;\n\r" /*传入参赛:文件描述符(stdout)*/ "mov $1, %%ebx;\n\r" /*传入参数:要显示的字符串*/ "mov $4, %%eax;\n\r" /*系统调用号:4 sys_write*/ "int $0x80" /*触发系统调用中断*/ :"=m"(result) /*输出部分:本例并未使用*/ :"m"(msg),"r"(len) /*输入部分:绑定字符串和字符串长度变量*/ :"%eax"); return 0;}
下面我们就基于上周完成的嵌入式汇编的代码完成本周的实验。
首先根据mooc的课程的要求执行实验第一部分:
1.更新menu代码到最新版。
cd LinuxKernelrm menu -rfgit clone https://github.com/mengning/menu.gitcd menu
2.在main函数中增加menuconfig。
3.增加对应的write和writeasm函数。
基于上节课调用函数的代码,编写代码如下:
#include#include #include #include int writetext() { write(1,"liuhongyi20169217",17); return 0;}int writeasm() { char* msg = "liuhongyi20169217"; int len = 17; int result = 0; asm volatile ( "mov %2, %%edx;\n\r" /*传入参数:要显示的字符串长度*/ "mov %1, %%ecx;\n\r" /*传入参赛:文件描述符(stdout)*/ "mov $1, %%ebx;\n\r" /*传入参数:要显示的字符串*/ "mov $4, %%eax;\n\r" /*系统调用号: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。我对于锁机制的理解是党多个线程抢占同一资源时,需要先行进入的的线程对资源进行锁定,待执行完成后,再释放资源给其他线程。