pthread_join(tid[i],NULL);;等待线程执行结束
}
return0;
}
实验五shell模拟程序的设计与实现
一、实验目的
1.理解shell的概念及其执行过程。
2.实现一个交互式shell,具备的功能至少有:
打印提示符,获取用户输入指令;解析指令;寻找命令文件,执行指令。
二、实验环境和工具
RedHatLinux
三、实验流程
1.明确程序的功能要求。
2.逐步实现程序功能:
打印提示符、获取用户输入命令、解析命令、寻找命令文件、执行命令。
代码见关键代码部分。
四、实验结果
五、实验心得
本次实验,让我学会了简单的shell模拟器的编程实现,理解了shell模拟器的工作原理和工作过程。
Shell是操作系统的用户界面,提供了用户与内核进行交互操作的接口,负责接收用户命令并把其送入内核去执行。
通过shell,用户可以方便的管理计算机资源。
Shell模拟器不断的接收用户指令并解析执行,直到用户关闭它,所以程序中要有一个while
(1)循环。
实验中我只实现了对几个常用指令的解释执行,基本模拟了shell的实现。
我感觉本次试验的难点是:
如何将用户输入的指令与系统中的指令正确对应;字符串操作不熟悉,一些函数不知道。
C语言提供了strncasecmp函数进行字符串比对,然后根据返回值进行相应的指令处理即可。
六、关键代码
while
(1){
path=get_current_dir_name();
memset(cmd,0,1024);
printf("@zhangyu%s>$",path);
fgets(cmd,1000,stdin);/*接受用户输入,命令最长1000个字符*/
cmd[strlen(cmd)-1]=0;/*去掉输入的回车符*/
b=transcmd(cmd);/*分析取得用户命令字*/
switch(b){
case9:
/*如果是Bye*/
printf("Seeyoulater!
\n");
break;
case1:
/*切换工作目录*/
if(chdir(cmd+3)!
=0){
printf("chdir(%s)error!
%s\n",cmd+3,strerror(errno));
}
break;
case2:
/*ls命令*/
case7:
/*cp命令*/
case8:
/*pwd命令*/
system(cmd);
break;
case3:
/*pid命令*/
printf("%d\n",getpid());
break;
case4:
/*rm命令*/
remove(cmd+3);
break;
case5:
/*mkdir命令*/
mkdir(cmd+6,0755);
break;
case6:
/*mv命令*/
p=strchr(cmd+3,'');
*p=0;
rename(cmd+3,p+1);
break;
case0:
/*不能识别的命令*/
printf("Badcommand,tryagain!
Allaviablecommandsare:
\nlogoutcdlspwdpidrmmkdirmvcp\n",getpid());
break;
}
}
}
chartranscmd(char*s)
{
if(!
strncasecmp(s,"cd",2))return1;
elseif(!
strncasecmp(s,"ls",2))return2;
elseif(!
strncasecmp(s,"pid",3))return3;
elseif(!
strncasecmp(s,"rm",2))return4;
elseif(!
strncasecmp(s,"mkdir",5))return5;
elseif(!
strncasecmp(s,"mv",2))return6;
elseif(!
strncasecmp(s,"cp",2))return7;
elseif(!
strncasecmp(s,"pwd",3))return8;
elseif(!
strncasecmp(s,"bye",3))return9;
elsereturn0;
}
实验六系统调用
一、实验目的
1.理解系统调用过程
2.学会自己添加系统调用
二、实验环境和工具
RedHatLinux
三、实验流程
1.决定系统调用名字,本实验中叫__NR_print_info,内核中系统调用实现程序的名字:
sys_print_info。
之后在头文件unistd.h添加系统调用号,该文件所在目录是/usr/include/asm/unistd.h,如下:
2.在系统调用表中添加相应表项,系统调用表所在目录:
/usr/src/linux-2.4/arch/i386/kernel/entry.S
3.添加实现程序,目录:
/usr/src/linux2.4/kernel/sys.c
4.修改Makefile文件,将版本号改为-17(用来区别之前的系统)。
5.编译内核:
进入内核所在目录,依次输入如下命令:
makemrproper;makeclean;makemenuconfig;makedep;makebzImage;makemodules;makemodules_install
6.将生成的新内核移动到boot下并改名,操作如下:
cp/usr/src/linux-2.4/arch/i386/boot/bzImage/boot/vmlinuz-2.4.20-17;cp/usr/src/linux-2.4/System.map/boot/System.map-2.4.20-17;cd/boot;mkinitrdinitrd-2.4.20-17.img2.4.20-17
7.修改grup文件,添加新启动项
8.重启系统,进入新内核,编写测试程序,运行调试。
四、实验结果
五、实验心得
系统调用是内核提供的、功能十分强大的一系列函数,是用户程序与内核交互的一个接口。
通过本次实验,我理解了系统调用的实现过程,应用程序执行系统调用后,从用户态切换到内核态,之后在内核空间调用内核函数,执行完毕后从内核态切换回用户态。
实验中不好理解的一点是如何根据系统调用号259在系统调用表中找到相应表项。
系统调用表中有一句代码:
.reptNR_syscalls-(.-sys_call_table)/4.开始的“.”代表当前地址,sys_call_table代表数组首地址,所以两个变量相减,得到差值表示这个系统调用表的大小(字节数),之后再除以4(每个系统调用占四个字节),得到系统调用个数。
一开始我总是做不成功,是因为在添加系统调用号的时候添错了地方,我加在了/usr/src/linux-2.4/include/asm-i386/unistd.h,改正后便实现了。
六、关键代码
实验七FloppyLinux的实现
一、实验目的
1.了解linux的引导过程。
2.实现一款FloppyLinux。
二、实验环境和工具
RedHatLinux
工具:
busybox
三、实验流程
1.软盘安装引导器
a.对软盘建立ex2文件系统
#mke2fs/dev/fd0
b.将系统中grub目录下的引导文件stage1,stage2复制到软盘中
c.配置grub信息
2.配置busybox相关选项
Makemenuconfig
前三个选项中只选择第一项,其他默认。
3.编译并安装busybox
4.建立临时目录,该目录为软盘的文件系统
5.建立设备列表
6.建立启动配置文件(重点步骤)
7.制作镜像文件initrd.img
8.检查,用loop设备把镜像文件重新挂装到文件系统里,之后压缩镜像文件。
9.编译linux内核
注意makemenuconfig步骤,按照书上的要求来,最后我编译的内核大小为810k。
10.整合启动盘
11.测试
四、实验结果
五、实验心得
通过本次实验,我了解了linux系统的启动过程,进一步熟悉了linux内核编译过程。
学会了floppylinux的制作方法,做成之后非常有成就感。
我认为本实验并不难,考验的是细心。
实验步骤很多,每个步骤出现错误,都有可能导致实验失败。
所以要力求每个步骤准确无误,特别是建立启动配置文件的时候,要仔细核对每一个单词,特别注意空格。
第一遍没有成功,原因就出在这里。
总之,面对一个步骤复杂的事情,要细心。
六、关键代码
Inittab:
:
:
sysinit:
/etc/init.d/rcS
:
:
askfirst:
/bin/sh
rcS:
#!
/bin/sh
mount–a
#chmod755rc.sysinit
fstab:
proc/procprocdefaults00
grub.conf
timeout0
default10
titleFloppyLinux
root(fd0)
kernel/boot/bzImage
initrd/initrd.img.gz