操作系统实验报告

时间:2024.4.14

----华中科技大学计算机学院

操作系统课程设计

实 验 报 告

    级:         

    号:           

    名:            

指导教师:             

完成日期:     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<dos.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

{

    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,输入源代码。进入终端后使用编译命令:gcc copy2.c -o copy2 编译源代码。然后运行新生成文件./copy2,就会把source1.txt内的文字复制到source2.txt中(如果source2.txt不存在则会新建该文件)。结果如上图所示。

题目二:

源代码如下:

3.c:

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <sys/types.h>

#include <linux/sem.h>

int p1,p2;

int main (void)

{

    if((p1=fork())==0)

    {

         execv("./gtk1",NULL);

    }

    else                                

    {

         if((p2=fork())==0)

         {

             execv("./gtk2",NULL);

         }

         else

         {

             if (fork()==0)

             {

                  execv("./gtk3",NULL);

             }

         }

    }

    return 0;

}

gtk1.c:

#include <gtk/gtk.h>

 /* 传到这个函数的数据被打印到标准输出 */

void callback( GtkWidget *widget, gpointer   data )

{

    g_print ("Process 1- %s was pressed\n", (char *) data);

}

/* 这个回调退出程序 */

gint delete_event( GtkWidget *widget,GdkEvent  *event,gpointer   data )

{

    gtk_main_quit ();

    return FALSE;

}

int main( int   argc,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 ("button 1");

    /* 当这个按钮被点击时,我们调用 "callback" 函数,并将一个

     * 指向"button 1"的指针作为它的参数 */

    g_signal_connect (G_OBJECT (button), "clicked",

                  G_CALLBACK (callback), (gpointer) "button 1");

    /* 将button 1插入表的左上象限(quadrant) */

    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);

    gtk_widget_show (button);

    /* 创建第二个按钮 */

    button = gtk_button_new_with_label ("button 2");

    /* 当这个按钮被点击时,我们调用 "callback" 函数,并将一个

     * 指向"button 2"的指针作为它的参数 */

    g_signal_connect (G_OBJECT (button), "clicked",

                      G_CALLBACK (callback), (gpointer) "button 2");

    /* 将button 2插入表的右上象限 */

    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 ();

    return 0;

}

gtk2.c和gtk3.c的源代码与gtk1.c的大致相同。

依照源代码分别将gtk1.c、gtk1.c、gtk1.c和3.c文件编写好。进入终端后分别编译这几个文件。编译gtk1.c的命令为:

gcc gtk1.c -o gtk2 `pkg-config --cflags --libs gtk+-2.0`

因为该程序使用了gtk编程,所以需要在后面加上参数`pkg-config --cflags --libs gtk+-2.0`。编译3.c的命令与题目一中程序一样为:

gcc 3.c -o 3

编译完成后会生成相应的两个可执行文件。最后输入./3即可执行main程序,所得结果如上图所示,一共建立了3个进程process1、 process2和 process3。点击各自的quit按钮即可关闭所在的进程。

实验二

源代码如下:

系统调用代码:

asmlinkage int sys_filecopy(char* sourceFile,char* distFile)

  {

    int f1,f2,n;

    char buf[512];

    mm_segment_t fs;

    if((f1=sys_open(sourceFile,O_RDONLY,0)) ==-1){

        printk("Can't open %s\n",sourceFile);

        sys_exit(-1);

    }

    if((f2=sys_open(distFile,O_CREAT|O_WRONLY|O_TRUNC,0666))==-1){

        printk("Can't creat %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("write error on file %s",distFile);

       sys_exit(-1);

    }

  }

    set_fs(fs);

    sys_close(f1);

     sys_close(f2);

    return 0;

filecopy.c(测试代码):

 #include<linux/unistd.h>

#include</usr/src/linux-2.6.31.12/arch/x86/include/asm/unistd.h>

    #include<stdio.h>

#include<sys/syscall.h>

#define __NR_filecopy     337

 int main(int argc,char *argv[])

{

    int i;

    if(argc !=3)

    printf("error!");

    else

      {

         i=syscall(337,argv[0],argv[1]);

         printf("ok!");

        }

       return 0;

}

实验步骤如下:

1.将内核包linux-2.6.31.12.tar解压到 /usr/src 下。

2.增加新的系统调用,修改sys.c。

使用命令sudo gedit /usr/src/linux-2.6.31.12/kernel/sys.c打开sys.c文件,将系统调用的代码加入该文件中。

3.修改系统调用表syscall_table_32.S::

使用命令 sudo gedit /usr/src/linux-2.6.31.12/arch/x86/kernel/syscall_table_32.S打开系统调用表,在最后加上        .long sys_filecopy

4.增加新系统调用号,修改unistd.h

使用命令 sudo gedit /usr/src/linux-2.6.31.12/arch/x86/include/unistd_32.h打开该文件,在其中添加:#define   _ _NR_filecopy    337。

5.编译内核,依次输入以下命令:

sudo cd /usr/src/linux-2.6.31.12

sudo make menuconfig

sudo make bzImage

sudo make modules

sudo make modules_install

sudo cp arch/i386/boot/bzImage    /boot/vmlinuz-2.6.31.12

sudo mkinitramfs -o initrd.img-2.6.31.12    2.6.31.12

6.修改grub:

使用命令sudo gedit /boot/grub/grub.cfg 打开grub.cfg文件,仿照文件中的格式加入下列代码:

menuentry "Ubuntu, Linux 2.6.31.12" {

     insmod ntfs

     set root=(hd0,8)

     search --no-floppy --fs-uuid --set e67496277495fb0f

     loopback loop0 /ubuntu/disks/root.disk

     set root=(loop0)

     linux /boot/vmlinuz-2.6.31.12 root=/dev/sda8 loop=/ubuntu/disks/root.disk ro   quiet splash

     initrd /boot/inird-2.6.31.12.img

7.重启,导入新的内核,测试。

重启后选择Ubuntu, Linux 2.6.31.12进入,编译写好的测试文件filecopy.c。在终端中输入gcc filecopy.c -o filecopy 编译源代码,然后输入./filecopy  1.txt 2.txt运行新生成文件,如果1.txt不存在,则会报错,若存在,则成功复制。运行结果如上图所示,所达成的功能与实验一相同。

实验三

源代码如下:

device.c(驱动程序代码):

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

#define MAJOR_NUM 147

static ssize_t d_read(struct file *, char *, size_t, loff_t*);

static ssize_t d_write(struct file *, const char *, size_t, loff_t*);

static ssize_t d_open(struct inode *,struct file *);

static ssize_t d_release(struct inode *,struct file *);

struct file_operations d_fops=

{

     .read=d_read,

     .write=d_write,

     .open=d_open,

     .release=d_release,

};

static char var[1024]="Device test:";

int counter=12;

static int __init device_init(void)

{

     int result;

     result = register_chrdev(MAJOR_NUM, "device", &d_fops);

     if(result)

     {

         printk("device register failure");

     }

     else

     {

     printk("device register success");

     }

     return result;

}

static void __exit device_exit(void)

{

     unregister_chrdev(MAJOR_NUM, "device");

     printk("unloading the device...");

}

static ssize_t d_read(struct file *filp, char *buf, size_t len, loff_t *off)

{

     if(copy_to_user(buf,var,1024*sizeof(char)))

     {

         return - EFAULT;

     }

     return sizeof(char);

}

static ssize_t d_write(struct file *filp,const char *buf,size_t len,loff_t *off)

{

     if(copy_from_user(var+counter,buf,len*sizeof(char)))

     {

         return - EFAULT;

     }

     counter+=len;

     return sizeof(char);

}

static ssize_t d_open(struct inode *inode,struct file *file)

{

     printk(KERN_INFO "open it!\n");

     return 0;

}

static ssize_t d_release(struct inode *inode,struct file *file)

{

     printk(KERN_INFO "close it\n");

     return 0;

}

module_init(device_init);

module_exit(device_exit);

Makefile(Makefile文件):

ifneq ($(KERNELRELEASE),)   

#kbuild syntax.

mymodule-objs :=device.o   

obj-m := device.o       

else

PWD :=$(shell pwd)

KVER :=$(shell uname -r)

KDIR :=/lib/modules/$(KVER)/build

all:

     $(MAKE) -C $(KDIR) M=$(PWD)

clean:

     rm -f *.cmd *.o *.mod *.ko

endif

sdevice.c(测试程序代码):

#include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <fcntl.h>

#include <string.h>

main()

{

     int fd;

     char buffer[1024];

     int num;

     fd=open("/dev/device",O_RDWR,S_IRUSR|S_IWUSR);

     if(fd!=-1)

     {

         read(fd,buffer,1024*sizeof(char));

         printf("The device is %s\n",buffer);

         printf("Please input the characters written to device:\n");

         fgets(buffer,1024,stdin);

         num=strlen(buffer)-1;

         write(fd,buffer,num*sizeof(char));

         read(fd,buffer,1024*sizeof(char));

         printf("The device is %s\n",buffer);

         close(fd);

     }

     else

     {

         printf("Device open failure\n");

     }

}

首先依照源代码分别创建相应的3个文件并保存。其中device.c和Makefile要保存在一个文件夹下。

然后依次输入以下命令:

sudo  make       (此时在device.c所在文件夹内会生成数个文件)

sudo  insmod  -f  device.ko

sudo  cat  /proc/devices

在出现的项目中寻找device项,记住其对应的设备号(本次为147)。

输入命令sudo  mknod  /dev/device  c  147  0,其中c指创建字符设备,第一个参数为主设备号,第二个从设备号为0。

之后即可编译并执行测试程序了。调试过程及结果如下图所示:

运行调试程序时需使用命令sudo  ./sdevice,否则就会出现上图中出现的错误提示。

最后使用命令sudo  rmmod  device即可卸载驱动。

四、心得体会:

此次课程设计在linux平台上进行的,还是充满了好奇的,当在同学的指导下完成部分实验时内心还是很开心的。

自己对程序设计不是很感兴趣,学得也不杂样,在余建同学的帮助下完成此次课程设计的,在同学的帮助下练习了实验的操作,不过通过实验还是收获了不少,第一次切身使用linux系统,在linux系统下还进行了许多其它操作,体会到了它与windows的很大不同,当用linux完成很多平时在windows下觉得很简单的任务时,觉得很惊奇。

实验操作中也学会了许多命令,了解了一些linux命令的使用方法。比如说许多命令前都要加上sudo来修改访问权限,否则系统就无法执行相关的指令,开始操作的时候总是忽略,造成错误,后来了解后才在后来的操作中没有犯同样的错误。

虽然此次课程设计没有认认真真地花花很大精力去做,但是还是收获了不少。

更多相关推荐:
操作系统实验报告 完全版

《计算机操作系统》实验报告班级:姓名:学号:实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。通过创建进程、观察正在运行的进…

操作系统实验报告

操作系统实验报告实验名称理解UNIXLINUXShell及UNIX的进程树成绩专业班级计科姓名学号联系电话实验日期20xx年12月5日实验报告日期20xx年12月5日一实验名称理解UNIXLINUXShell及...

操作系统实验报告

目录实验一进程的创建2实验二进程控制3实验三进程的管道通信4实验四消息通信6实验五进程调度算法8实验六FIFO页面置换算法12实验七LRU页面置换算法14实验八磁盘调度18实验一进程的创建1一实验目的编写一段程...

操作系统实验报告

操作系统实验报告学号姓名班级实验一实验报告实验名称并发程序设计实验1实验目的掌握在程序中创建新进程的方法观察并理解多道程序并发执行的现象实验原理fork建立子进程子进程得到父进程地址空间的一个复制返回值成功时该...

计算机操作系统课程设计报告

《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.........................................…

操作系统课程设计实验报告

操作系统课程设计实验报告姓名学号班级地点20xx年月日任务说明共完成四个任务任务一IO系统调用开销比较任务二实现一个简单的shell任务三进程线程同步任务四文件内容的并行搜索其中任务一完成了标准c和unix下的...

操作系统实验报告

郑州航空工业管理学院计算机科学与应用系课程设计报告操作系统原理操作系统课程设计目录1题目简述22需求分析221设计思想222要求323任务324运行环境325开发工具33概要设计与详细设计331系统流程图332...

操作系统进程控制实验报告

操作系统实验报告实验题目进程控制专业计算机科学与技术学生姓名班级学号120xx715指导教师指导单位计算机学院日期20xx年11月13日一实验目的1学习和了解进程控制的基本和常用的系统调用forkwaitsle...

操作系统 综合实验报告

华北科技学院计算机学院综合性实验实验报告课程名称计算机操作系统实验学期20xx至20xx学年第1学期学生所在系部计算机年级大三专业班级计科B113学生姓名黄宋学号20xx07014313任课教师王祥仲实验成绩计...

操作系统实验报告三

操作系统实验报告实验序号03实验项目名称Windows控制台命令系统管理

操作系统第一次实验报告

操作系统实验报告实验名称线程控制实验计算机科学与技术学院目录一实验目的和要求2二实验内容2三实验步骤2四实验结果与分析31单线程32单线程睡眠4s33多线程44多线程每个子线程睡眠1s45单线程与多线程对比5五...

操作系统原理实验报告01

操作系统原理实验报告实验序号1实验项目名称Windows文件操作命令

操作系统实验报告(38篇)