操作系统实验报告.docx
《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
![操作系统实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/21/1e15f015-261a-4d4d-8dc4-5f97bcd57182/1e15f015-261a-4d4d-8dc4-5f97bcd571821.gif)
操作系统实验报告
----华中科技大学计算机学院
操作系统课程设计
实验报告
班级:
学号:
姓名:
指导教师:
完成日期:
2010-04-02
一、实验目的:
1.掌握Linux操作系统的使用方法;
2.了解Linux系统内核代码结构;
3.掌握实例操作系统的实现方法。
二、实验题目:
1.掌握Linux操作系统的使用方法,包括键盘命令、系统调用;掌握在Linux下的编程环境。
1)编一个C程序,其内容为实现文件拷贝的功能;
2)编一个C程序,其内容为分窗口同时显示三个并发进程的运行结果。
要求用到Linux下的图形库。
2.掌握系统调用的实现过程,通过编译内核方法,增加一个新的系统调用。
另编写一个应用程序,调用新增加的系统调用。
实现的功能是:
文件拷贝;
3.掌握增加设备驱动程序的方法。
通过模块方法,增加一个新的设备驱动程序,其功能可以简单。
实现字符设备的驱动。
4.了解和掌握/proc文件系统的特点和使用方法
(1)了解/proc文件的特点和使用方法
(2)监控系统状态,显示系统中若干部件使用情况
(3)用图形界面实现系统监控状态。
5.设计并实现一个模拟的文件系统(选做)
三、实验步骤及源代码:
实验一
题目一:
源代码如下:
#include
#include
#include
#include
intmain()
{
FILE*f1,*f2;
f1=fopen("d:
\\source1.txt","r");
f2=fopen("d:
\\source2.txt","w");
while(!
feof(f1))
{
fputc(fgetc(f1),f2);
}
fclose(f1);
fclose(f2);
printf("拷贝完成!
!
\n");
}
创建文件copy.c,输入源代码。
进入终端后使用编译命令:
gcccopy2.c-ocopy2编译源代码。
然后运行新生成文件./copy2,就会把source1.txt内的文字复制到source2.txt中(如果source2.txt不存在则会新建该文件)。
结果如上图所示。
题目二:
源代码如下:
3.c:
#include
#include
#include
#include
#include
intp1,p2;
intmain(void)
{
if((p1=fork())==0)
{
execv("./gtk1",NULL);
}
else
{
if((p2=fork())==0)
{
execv("./gtk2",NULL);
}
else
{
if(fork()==0)
{
execv("./gtk3",NULL);
}
}
}
return0;
}
gtk1.c:
#include
/*传到这个函数的数据被打印到标准输出*/
voidcallback(GtkWidget*widget,gpointerdata)
{
g_print("Process1-%swaspressed\n",(char*)data);
}
/*这个回调退出程序*/
gintdelete_event(GtkWidget*widget,GdkEvent*event,gpointerdata)
{
gtk_main_quit();
returnFALSE;
}
intmain(intargc,char*argv[])
{
GtkWidget*window;
GtkWidget*button;
GtkWidget*table;
gtk_init(&argc,&argv);/*创建一个新窗口*/
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
/*设置窗口标题*/
gtk_window_set_title(GTK_WINDOW(window),"进程一");
/*为delete_event设置一个立即退出GTK的处理函数。
*/
g_signal_connect(G_OBJECT(window),"delete_event",
G_CALLBACK(delete_event),NULL);
/*设置窗口的边框宽度。
*/
gtk_container_set_border_width(GTK_CONTAINER(window),20);
/*创建一个2x2的表*/
table=gtk_table_new(2,2,TRUE);
/*将表放进主窗口*/
gtk_container_add(GTK_CONTAINER(window),table);
/*创建第一个按钮*/
button=gtk_button_new_with_label("button1");
/*当这个按钮被点击时,我们调用"callback"函数,并将一个
*指向"button1"的指针作为它的参数*/
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(callback),(gpointer)"button1");
/*将button1插入表的左上象限(quadrant)*/
gtk_table_attach_defaults(GTK_TABLE(table),button,0,1,0,1);
gtk_widget_show(button);
/*创建第二个按钮*/
button=gtk_button_new_with_label("button2");
/*当这个按钮被点击时,我们调用"callback"函数,并将一个
*指向"button2"的指针作为它的参数*/
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(callback),(gpointer)"button2");
/*将button2插入表的右上象限*/
gtk_table_attach_defaults(GTK_TABLE(table),button,1,2,0,1);
gtk_widget_show(button);
/*创建"Quit"按钮*/
button=gtk_button_new_with_label("Quit");
/*当这个按钮被点击时,我们调用"delete_event"函数接着
*程序就退出了*/
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(delete_event),NULL);
/*将退出按钮插入表的下面两个象限*/
gtk_table_attach_defaults(GTK_TABLE(table),button,0,2,1,2);
gtk_widget_show(button);
gtk_widget_show(table);
gtk_widget_show(window);
gtk_main();
return0;
}
gtk2.c和gtk3.c的源代码与gtk1.c的大致相同。
依照源代码分别将gtk1.c、gtk1.c、gtk1.c和3.c文件编写好。
进入终端后分别编译这几个文件。
编译gtk1.c的命令为:
gccgtk1.c-ogtk2`pkg-config--cflags--libsgtk+-2.0`
因为该程序使用了gtk编程,所以需要在后面加上参数`pkg-config--cflags--libsgtk+-2.0`。
编译3.c的命令与题目一中程序一样为:
gcc3.c-o3
编译完成后会生成相应的两个可执行文件。
最后输入./3即可执行main程序,所得结果如上图所示,一共建立了3个进程process1、process2和process3。
点击各自的quit按钮即可关闭所在的进程。
实验二
源代码如下:
系统调用代码:
asmlinkageintsys_filecopy(char*sourceFile,char*distFile)
{
intf1,f2,n;
charbuf[512];
mm_segment_tfs;
if((f1=sys_open(sourceFile,O_RDONLY,0))==-1){
printk("Can'topen%s\n",sourceFile);
sys_exit(-1);
}
if((f2=sys_open(distFile,O_CREAT|O_WRONLY|O_TRUNC,0666))==-1){
printk("Can'tcreat%s,mode%o\n",distFile,0666);
sys_exit(-1);
}
fs=get_fs();
set_fs(get_ds());
while((n=sys_read(f1,buf,512))>0)
{if(sys_write(f2,buf,n)!
=n){
printk("writeerroronfile%s",distFile);
sys_exit(-1);
}
}
set_fs(fs);
sys_close(f1);
sys_close(f2);
return0;
filecopy.c(测试代码):
#include
#include
#include
#include
#define__NR_filecopy337
intmain(intargc,char*argv[])
{
inti;
if(argc!
=3)
printf("error!
");
else
{
i=syscall(337,argv[0],argv[1]);
printf("ok!
");
}
return0;
}
实验步骤如下:
1.将内核包linux-2.6.31.12.tar解压到/usr/src下。
2.增加新的系统调用,修改sys.c。
使用命令sudogedit/usr/src/linux-2.6.31.12/kernel/sys.c打开sys.c文件,将系统调用的代码加入该文件中。
3.修改系统调用表syscall_table_32.S:
:
使用命令sudogedit/usr/src/linux-2.6.31.12/arch/x86/kernel/syscall_table_32.S打开系统调用表,在最后加上.longsys_filecopy
4.增加新系统调用号,修改unistd.h
使用命令sudogedit/usr/src/linux-2.6.31.12/arch/x86/include/unistd_32.h打开该文件,在其中添加:
#define__NR_filecopy337。
5.编译内核,依次输入以下命令:
sudocd/usr/src/linux-2.6.31.12
sudomakemenuconfig
sudomakebzImage
sudomakemodules
sudomakemodules_install
sudocparch/i386/boot/bzImage/boot/vmlinuz-2.6.31.12
sudomkinitramfs-oinitrd.img-2.6.31.122.6.31.12
6.修改grub:
使用命令sudogedit/boot/grub/grub.cfg打开grub.cfg文件,仿照文件中的格式加入下列代码:
menuentry"Ubuntu,Linux2.6.31.12"{
insmodntfs
setroot=(hd0,8)
search--no-floppy--fs-uuid--sete67496277495fb0f
loopbackloop0/ubuntu/disks/root.disk
setroot=(loop0)
linux/boot/vmlinuz-2.6.31.12root=/dev/sda8loop=/ubuntu/disks/root.diskroquietsplash
initrd/boot/inird-2.6.31.12.img
7.重启,导入新的内核,测试。
重启后选择Ubuntu,Linux2.6.31.12进入,编译写好的测试文件filecopy.c。
在终端中输入gccfilecopy.c-ofilecopy编译源代码,然后输入./filecopy1.txt2.txt运行新生成文件,如果1.txt不存在,则会报错,若存在,则成功复制。
运行结果如上图所示,所达成的功能与实验一相同。
实验三
源代码如下:
device.c(驱动程序代码):
#include
#include
#include
#include
MODULE_LICENSE("GPL");
#defineMAJOR_NUM147
staticssize_td_read(structfile*,char*,size_t,loff_t*);
staticssize_td_write(structfile*,constchar*,size_t,loff_t*);
staticssize_td_open(structinode*,structfile*);
staticssize_td_release(structinode*,structfile*);
structfile_operationsd_fops=
{
.read=d_read,
.write=d_write,
.open=d_open,
.release=d_release,
};
staticcharvar[1024]="Devicetest:
";
intcounter=12;
staticint__initdevice_init(void)
{
intresult;
result=register_chrdev(MAJOR_NUM,"device",&d_fops);
if(result)
{
printk("deviceregisterfailure");
}
else
{
printk("deviceregistersuccess");
}
returnresult;
}
staticvoid__exitdevice_exit(void)
{
unregister_chrdev(MAJOR_NUM,"device");
printk("unloadingthedevice...");
}
staticssize_td_read(structfile*filp,char*buf,size_tlen,loff_t*off)
{
if(copy_to_user(buf,var,1024*sizeof(char)))
{
return-EFAULT;
}
returnsizeof(char);
}
staticssize_td_write(structfile*filp,constchar*buf,size_tlen,loff_t*off)
{
if(copy_from_user(var+counter,buf,len*sizeof(char)))
{
return-EFAULT;
}
counter+=len;
returnsizeof(char);
}
staticssize_td_open(structinode*inode,structfile*file)
{
printk(KERN_INFO"openit!
\n");
return0;
}
staticssize_td_release(structinode*inode,structfile*file)
{
printk(KERN_INFO"closeit\n");
return0;
}
module_init(device_init);
module_exit(device_exit);
Makefile(Makefile文件):
ifneq($(KERNELRELEASE),)
#kbuildsyntax.
mymodule-objs:
=device.o
obj-m:
=device.o
else
PWD:
=$(shellpwd)
KVER:
=$(shelluname-r)
KDIR:
=/lib/modules/$(KVER)/build
all:
$(MAKE)-C$(KDIR)M=$(PWD)
clean:
rm-f*.cmd*.o*.mod*.ko
endif
sdevice.c(测试程序代码):
#include
#include
#include
#include
#include
main()
{
intfd;
charbuffer[1024];
intnum;
fd=open("/dev/device",O_RDWR,S_IRUSR|S_IWUSR);
if(fd!
=-1)
{
read(fd,buffer,1024*sizeof(char));
printf("Thedeviceis%s\n",buffer);
printf("Pleaseinputthecharacterswrittentodevice:
\n");
fgets(buffer,1024,stdin);
num=strlen(buffer)-1;
write(fd,buffer,num*sizeof(char));
read(fd,buffer,1024*sizeof(char));
printf("Thedeviceis%s\n",buffer);
close(fd);
}
else
{
printf("Deviceopenfailure\n");
}
}
首先依照源代码分别创建相应的3个文件并保存。
其中device.c和Makefile要保存在一个文件夹下。
然后依次输入以下命令:
sudomake(此时在device.c所在文件夹内会生成数个文件)
sudoinsmod-fdevice.ko
sudocat/proc/devices
在出现的项目中寻找device项,记住其对应的设备号(本次为147)。
输入命令sudomknod/dev/devicec1470,其中c指创建字符设备,第一个参数为主设备号,第二个从设备号为0。
之后即可编译并执行测试程序了。
调试过程及结果如下图所示:
运行调试程序时需使用命令sudo./sdevice,否则就会出现上图中出现的错误提示。
最后使用命令sudormmoddevice即可卸载驱动。
四、心得体会:
此次课程设计在linux平台上进行的,还是充满了好奇的,当在同学的指导下完成部分实验时内心还是很开心的。
自己对程序设计不是很感兴趣,学得也不杂样,在余建同学的帮助下完成此次课程设计的,在同学的帮助下练习了实验的操作,不过通过实验还是收获了不少,第一次切身使用linux系统,在linux系统下还进行了许多其它操作,体会到了它与windows的很大不同,当用linux完成很多平时在windows下觉得很简单的任务时,觉得很惊奇。
实验操作中也学会了许多命令,了解了一些linux命令的使用方法。
比如说许多命令前都要加上sudo来修改访问权限,否则系统就无法执行相关的指令,开始操作的时候总是忽略,造成错误,后来了解后才在后来的操作中没有犯同样的错误。
虽然此次课程设计没有认认真真地花花很大精力去做,但是还是收获了不少。