资源描述
实验三:内核进程间通信的实现一、实验目的1、掌握 linux 内核进程间通信的设计2、了解向内核中添加新的系统调用的方法二、实验内容流管道(stream pipe )是一种全双工的管道。单个流管道就能向父、子进程提供双向 的数据。流管道最早出现在 4.2BSD 和 SVR3.2 系统中,但至今在 Linux 内核中还没有实现。本实验要求读者在 2.6 Linux 内核中基于 pipefs 实现流管道。 实验要求如下:a) 增加系统调用 int s_pipe(int filedes2);并实现 do_s_pipe()。b) 返回的filedesO和filedes1既可用于读操作也可用于写操作。c) 父进程调用s_pipe系统调用后创建子进程。父进程和子进程要求能够使用s_pipe返回的fd进行双向的数据通信。三、准备知识Linux 内核中所有的系统调用都维护在一张名为 sys_call_table 的表中,每一个系统调用函数在表中的顺序即为这个系统调用号。这个号码在用户进程提 出系统调用请求时被传递到内核,用来唯一的标识一个系统调用。所以,向内核 中添加一个新的系统调用首先需要分配一个新的系统调用号,并将其发布(通常 使用 include/asm/unistd.h 文件)。然后修改系统调用表,把新的系统调用函 数添加到系统调用号所对应的位置。这样,用户就可以根据这个号码来使用相应 的系统调用。例如:# define _NR_s_pipe 324# define SYS_s_pipe _NR_s_pipeint main()if (ret = syscall(SYS_s_pipe, fd) = -1) printf(s_pipe error: %sn”, strer(rerrono);return ret;四、参考代码(代码针对Linux 2.6.18内核版本)增加新的系统调用函数 sys_s_pipe()asmlinkage int sys_s_pipe(unsigned long _user * fildes)int fd2;int error;error = do_s_pipe(fd);if (!error) if (copy_to_user(fildes, fd, 2*sizeof(int)error = -EFAULT;return error;在文件 arch/i386/kernel/syscall_table.S 的 sys_call_table 中添加 sys_s_pipe 函数 名.long sys_s_pipe流管道功能实现struct file *create_s_pipe(void)int err;struct inode *inode;struct file *f;struct dentry *dentry;struct qstr name = .name = ;f = get_empty_filp();if (!f)return ERR_PTR(-ENFILE);err = -ENFILE;inode = get_pipe_inode();if (!inode)goto err_file;err = -ENOMEM;dentry = d_alloc(pipe_mnt-mnt_sb-s_root, &name);if (!dentry)goto err_inode;dentry-d_op = &pipefs_dentry_operations;/* We dont want to publish this dentry into global dentry hash table.* We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED* This permits a working /proc/$pid/fd/XXX on pipes*/dentry-d_flags &= DCACHE_UNHASHED;d_instantiate(dentry, inode);f-f_path.mnt = mntget(pipe_mnt);f-f_path.dentry = dentry;f-f_mapping = inode-i_mapping;f-f_flags = O_RDWR;f-f_op = &rdwr_pipe_fops;f-f_mode = FMODE_READ | FMODE_WRITE;f-f_version = 0;return f;err_inode:free_pipe_info(inode);iput(inode);err_file:put_filp(f);return ERR_PTR(err);void free_s_pipe(struct file *f)free_pipe_info(f-f_dentry-d_inode);dput(f-f_path.dentry);mntput(f-f_path.mnt);put_filp(f);int do_s_pipe(int *fd)struct file *f1, *f2;int error;int fd1, fd2;f1 = create_s_pipe();if (IS_ERR(f1)return PTR_ERR(f1);f2 = create_s_pipe();error = PTR_ERR(f2);if (IS_ERR(f2)goto err_s_pipe1;error = get_unused_fd();if (error 0)goto err_s_pipe2;fd1 = error;error = get_unused_fd();if (error 0)goto err_fd;fd2 = error;fd_install(fd1, f1);fd_install(fd2, f2);fd0 = fd1;fd1 = fd2;return 0;err_fd:put_unused_fd(fd1);err_s_pipe2:free_s_pipe(f2);err_s_pipe1:free_s_pipe(f1);return error;在文件 include/asm-i386/unistd.h 中发 布 s_pipe 的系统调用号码并修改系统调用函数总数#define _NR_s_pipe324#define NR_syscalls 325
展开阅读全文