重大linux实验报告1.doc
报告创建时间linux操作系统实验报告年级、专业、班级姓名实验题目Linux内核编译与系统调用实验时间2014/4/16实验地点A区主教学楼0414实验成绩实验性质□验证性□设计性□综合性教师评价□算法/实验过程正确;□源程序/实验内容提交□程序结构/实验步骤合理;□实验结果正确;□语法、语义正确;□报告规范;其他评价教师签名一、实验目的(1)掌握linux内核编译过程(2)掌握fork()和clone()创建进程二、实验项目内容1)Linux内核编译;2)分别用fork()和clone()创建进程列出子进程和父进程的进程号、进程名和进程状态等信息;3、实验过程或算法(源程序)编译内核为何要重新编译内核Linux作为一个自由软件,在广大爱好者的支持下,内核版本不断更新。新的内核修订了旧内核的bug,并增加了许多新的特性。如果用户想要使用这些新特性,或想根据自己的系统度身定制一个更高效,更稳定的内核,就需要重新编译Linux内核。通常,更新的内核会支持更多的硬件,具备更好的进程管理能力,运行速度更快、更稳定,并且一般会修复老版本中发现的许多漏洞等,经常性地选择升级更新的系统内核是Linux使用者的必要操作内容。一、打开虚拟机,poweronUbuntu。二、在登陆界面输入密码123456三、将linux-3.4.38.tar.xz包移动到“主文件夹”目录下四、打开命令终端ctrlaltt;查看当前内核版本号uname-a获取root权限sudosu提示输入密码123456五、解压源代码包xz–dlinux-3.4.38.tar.xztarxvflinux-3.4.38.tar/usr/src/linux-3.4.38六、编译内核喽(一)清除当前目录下残留的.config和.o文件在终端中进入刚刚的这个/usr/src/linux-3.4.38文件夹,输入命令makemrproper当然我们这里是第一次编译这个内核,所以不存在清理不清理,如果以后需要对这个内核重新编译,这一步骤当然是十分必要的啦。(二)安装ncurses作为操作系统的内核,其内容和功能必然非常繁杂,包括处理器调度,内存管理,文件系统管理,进程通讯以及设备管理等等,而对于不同的硬件,其配置选项也不相同,所以在编译源代码之前必须设置编译选项。其实我觉得这一步是升级内核整个过程中最有技术含量的,因为要根据自己的需要正确选择yesorno需要对计算机方方面面的知识都有所了解。但是这里的选项实在是太多了,大概有几百项之多,我以前曾尝试着一项一项的选,但是最后还是放弃了,因为有很多选项不是很明白。既然这样,难道没有什么简便的方法么当然有那就是makemenuconfig或者makexconfig。我使用的是makemenuconfig,但是前提条件是要装ncurses。对于下载好的这个ncurses包,我们把它放到/usr/local下面;接着终端进入这个文件夹cd/usr/local。解压缩并且释放文件包tarzxvfncurses.tar.gz按照你的系统环境制作安装配置文件./configure编译源代码并且编译NCURSES库make切换到root用户环境makeinstall这样我们的ncurses库就已经编译完成了。(三)配置内核编译选项在makemenuconfig过程中也会有一些选项需要你来设置*,y,n或者m,选择*表示选项中的内容被直接编入内核中,选择m表示选项中的内容编入内核,而只是编成独立的module,用到时才调用。在当前文件路径下,输入命令makemenuconfig这里就出现了一个配置选项的图形化界面,因为我们是用的虚拟机,所以一定要选择把SCSI设备编译进去。最后保存为.config文件并退出。(四)编译内核这步是时间最长的一个步骤,一般在3个小时左右。编译内核只需在终端输入make,然后等待编译的完成。(五)编译和安装内核模块输入makemodules_install,这步很快能完成。(六)安装内核输入makeinstall(七)生成启动依次输入sudomkinitramfs-o/boot/initrd.img-2.6.36sudoupdate-initramfs-c-k2.6.36sudoupdate-grub2//自动修改系统引导配置,产生grub.cfg启动文件。用fork和clone分别创建进程,并列出子进程和父进程的进程号、进程名和进程状态。Fork一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。fork创建一个子进程,即intpidfork,fork进入内核,调用一次返回两次,如果返回的pid0子进程先返回,如果pid0(此时返回的是子进程的pid),父进程先返回。至于子进程和父进程哪个先返回,要看内核的调度算法。输出次序乱序,都有可能。父进程和子进程是并发执行的。返回指的是这个函数returnpid;这个语句被执行了两次。因为创建了一个子进程后,那么子进程中的fork也要返回一次。在Linux下如果内存没有被写的话,那么父子进程是共用内存空间的,所以内存中的同一个fork函数会在两个进程中调用到。在父进程中返回的就是子进程id,子进程中返回的是0.Clone我们这里主要用带参数的clone函数来创建“轻量级的进程”线程。线程的创建和普通进程的创建类似,只不过在调用clone的时候需要传递一些参数标志来指明需要共享的资源intcloneint*fnvoid*,void*child_stack,intflags,void*arg;这里fn是函数指针,我们知道进程的4要素,这个就是指向程序的指针,就是所谓的“剧本,child_stack明显是为子进程分配系统堆栈空间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块task_struct的值),flags就是标志用来描述你需要从父进程继承那些资源,arg就是传给子进程的参数)。下面是flags可以取的值CLONE_PARENT创建的子进程的父进程是调用者的父进程,新进程与创建它的进程成了“兄弟”而不是“父子”CLONE_FS子进程与父进程共享相同的文件系统,包括root、当前目录、umaskCLONE_FILES子进程与父进程共享相同的文件描述符(filedescriptor)表CLONE_NEWNS在新的namespace启动子进程,namespace描述了进程的文件hierarchyCLONE_SIGHAND子进程与父进程共享相同的信号处理(signalhandler)表CLONE_PTRACE若父进程被trace,子进程也被traceCLONE_VFORK父进程被挂起,直至子进程释放虚拟内存资源CLONE_VM子进程与父进程运行于相同的内存空间CLONE_PID