操作系统课程设计全攻略

Windforce 发表于 2008-10-23 20:05:33

题目一:Linux系统调用

步骤:
1>
修改 arch/i386/kernel/entry.S, 增加新的系统调用表项
修改后的代码:
.long SYMBOL_NAME(sys_ni_syscall)    /* streams2 */
.long SYMBOL_NAME(sys_vfork)        /* 190 */
/*
* NOTE!! ...
*/
.rept NR_syscalls - 190
.long SYMBOL_NAME(sys_ni_syscall)

2>
修改 kernel/sys.c, 增加新的系统调用实现
asmlinkage int sys_mycall (int a, int b)
{  
int c=13061099;      //你的学号
printk(“IN_SYSCALL: my number is %d\n”,c);
return c;
}

3>
修改 include/asm/unistd.h, 增加新的系统调用编号
#define  __NR_mycall  191  /* my syscall */

4>
通过编译产生新内核,并重启操作系统。编译过程需严格输入以下命令即可(在/usr/src/linux/目录下输入)
make mrproper   /* clean old config info */
make clean      /* clean old object file */
make menuconfig /* do nothing,just exit and save config,all use default */
make dep        /* binding the configuration info */
make bzimage    /* it should work. */
cp arch/i386/boot/bzimage /boot/bzimage_00
mkinitrd /boot/bzImage_00.img 2.2.14-15mdk
vi /etc/lilo.conf /* add the new bzimage_00 to lilo */
lilo
reboot
Windforce提醒:修改lilo.conf时找上面的样子添加一个你自己的即可,即在文件最后添加类似如下的文字:
image=/boot/bzImage_00
 label=Windforce //把Windforce改称你自己想起的名字
 root=/dev/sda5
 initrd=/boot/bzImage_00.img
 append=""
 read-only


5>
对于内核本身提供的系统调用,在libc中都已经提供了相应的API,可以当做普通的库函数调用:
对于自定义的系统调用,需要经过特殊处理
#include <linux/unistd.h>
/* generate the stub for our new syscall
* int  sys_mycall(int a, int b)
*/
_syscall2 (int, mycall, int, a,  int, b);

Windforce提醒:注意_syscall后的2,表示mycall由两个参数,若你不想用两个参数,要改_syscall后的数字,否则编译内核会出错。

6>
重起时按住Tab键,然后进入你自己定义的启动模式
然后编写一段代码来运行,例:

#include<linux/unistd.h>

_syscall2(int, mycall ,int ,a,int ,b);
int main()
{
int a=0;
int b=0;
mycall( a, b);
return 0;
}


题目二:设备驱动

步骤:
1>
先照ppt上的内容写rwbuf.h:

#define   RWBUF_NAME  "rwbuf"           // 设备文件 /dev/rwbuf
#define   RWBUF_DEV   "/dev/rwbuf"  // device path
#define  RWBUF_MAJOR  60                  // 主设备号
#define  RWBUF_CLEAR   0x909090     // IO Ctrl Command
#define rwbuf_size 200             // MAX size of buffer

int init_module();
void cleanup_module();
static int  rwbuf_open ( struct inode *inode,  struct file * filep );
static int rwbuf_close( struct inode *inode,  struct file * filep );
static ssize_t rwbuf_write ( struct file * filep,    const char *buf,
                                           size_t   count,   loff_t * ppos );
static ssize_t rwbuf_read( struct file* filep,   char * buf,
                                          size_t count,       loff_t* ppos);
static int  rwbuf_ioctl  (  struct inode *inode,   struct file * filep,
   unsigned int cmd,
   unsigned long arg );

2>
再按照ppt上的内容写rwbuf.c

#include "rwbuf.h"
#include <linux/kernel.h>    // for kernel programming
#include <linux/module.h>    //  for kernel module struct.
#include <linux/fs.h>     //  struct file_operations
#include <linux/modversions.h>

#define  rwbuf_size  200    // MAX size of buffer
static char  rwbuf[rwbuf_size];   // the buffer keeping string
static int     rwlen = 0;    // length of string
static int inuse=0;      // only one process permited at the

same time

//char * buf = "TEST TEXT"                // Just a TEST

static int rwbuf_open ( struct inode *inode,  struct file * filep )  {
    if (inuse == 1) 
  return -1;
    inuse = 1;
 MOD_INC_USE_COUNT; // increase the use count in struct module
 return 0;
}

static int rwbuf_close( struct inode *inode,  struct file * filep ) {
 inuse  =  0;
 MOD_DEC_USE_COUNT;
 return 0;
}

static ssize_t rwbuf_write ( struct file * filep, const char *buf, size_t count, loff_t * ppos )
{
 // 判断写入的长度是否有效
 __generic_copy_from_user(rwbuf, buf, count); // 从用户空间复制到内核空间
 rwlen = count;
 printk("%s",buf);
 printk("Write MSG successed!\n");
 return count;
}

static ssize_t rwbuf_read( struct file* filep, char *buf, size_t count, loff_t* ppos){
 // 判断读取的长度是否有效
 __generic_copy_to_user( buf, rwbuf, count); // 从内核空间复制到用户空间
 printk("Read MSG successed!\n");
 return count;
}

static int  rwbuf_ioctl  (struct inode *inode, struct file * filep,
        unsigned int cmd,unsigned long arg )
{
 if ( cmd == RWBUF_CLEAR )  {
  rwlen = 0; // clear buf by set its len to zero
  printk("rwbuf in kernel zero-ed\n");
 };

 return 0;
}

static struct file_operations rwbuf_fops =
{
 open:  rwbuf_open,
 release: rwbuf_close,
 read:  rwbuf_read,
 write:  rwbuf_write,
 ioctl:  rwbuf_ioctl,
};

int init_module(){
      printk("Hello world\n");
      if ( register_chrdev( RWBUF_MAJOR, RWBUF_NAME, &rwbuf_fops)){ 
    printk("register error\n");
    return -1;
   }
   printk("register ok\n");
   return 0;
}

void cleanup_module()
{
    if (unregister_chrdev(  RWBUF_MAJOR, RWBUF_NAME)  !=0  )
  printk("unreg err\n");
    else
  printk("unreg ok\n");
 printk("bye\n");
}

 

3>
编译rwbuf.c,注意,编译命令爆长无比,不下心写错会导致之后加载不成功
编译命令(没有回车只有空格,注意下划线是两个连在一起的):
gcc -c -Wall -D__KERNEL__ -DMODULE  -include /usr/src/linux/include/linux/modversions.h -I /usr/src/linux/include rwbuf.c

4>
重起,按住Tab,选择进入linux-up环境

5>
安装设备驱动:
mknod  /dev/rwbuf  c  60  0 创建设备文件
/sbin/insmod   rwbuf.o   安装设备驱动

6>
自己写一段代码调用你的设备驱动里的函数,编译运行.例:

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define RWBUF_DEV "/dev/rwbuf"
#define RWBUF_CLEAR 0x909090

int main()
{
char yourmsg[18] = "Windforce gets it\n";
char tmp[10];
int h = open(RWBUF_DEV, O_RDONLY);
int n = read (h, tmp, sizeof(tmp));
close(h);
h = open(RWBUF_DEV, O_RDWR);
n =ioctl (h, RWBUF_CLEAR, 0);
close(h);
h = open(RWBUF_DEV, O_WRONLY);
n = write (h, yourmsg, sizeof(yourmsg)+1);
close(h);
}

7>
卸载:
/sbin/rmmod    rwbuf   卸载设备驱动

 

第三题:使用SpinLock实现进程的调度

步骤:
1>

编写自旋锁及其应用程序,编译运行.例:

#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/shm.h>

pid_t mcp;

int  spinlock(int *p)
{
 asm (
  "pushl %%eax; \n\t"
  "pushl %%ecx; \n\t"
  "l1:  movl %1, %%ecx; \n\t"
  "movl %2, %%eax; \n\t"
  "lock  cmpxchgl %%ecx, %0; \n\t"
  "jne l1; \n\t"
  "popl %%ecx; \n\t"
  "popl %%eax; \n\t"
  :"+m"(*p):"i"(1),"i"(0)
  :"%eax","%ecx"
  );
 return 0;
}


int spinunlock( int *lock )
{
 *lock = 0;
 return 0;
}

int spingetlock( int lock )
{
 return lock;
}

void init()
{
 int *l,*t,*lt;
 int i,j,k,h;
 int shmid;
 void * sharedmem = (void *)0;
 shmid = shmget((key_t)1234,9*sizeof(int), IPC_CREAT);
 if( shmid == -1 )
 {
  fprintf(stderr,"shmget failed\n");
  exit(EXIT_FAILURE);
 }
 sharedmem = shmat(shmid,(void *)0,0);
 if ( sharedmem  == (void*)-1 )
 {
  printf("shmat in init failed\n");
  exit(EXIT_FAILURE);
 }
 l = (int *)sharedmem;
 t = (int *)sharedmem + 3;
 lt = (int *)sharedmem + 6;
 for(h =0;h<3;h++)
 {
   l[h] = 1;
   t[h] = 0;
   lt[h] = 1;
 }

 for ( i = 0 ; i < 3 ; i++ )
 {
  if( ( mcp = fork() ) == 0 ) //childprocess ,i.e. a,b,c
  {
   if ( ( sharedmem = shmat(shmid,(void *)0,0) ) == (void*)-1  )
   {
    printf("shmat in %l failed\n",(long)getpid());
    exit(EXIT_FAILURE);
   }
   while(1)
   {
    if ( spingetlock( l[i] ) == 0 ) //l[i] is relesed , i.e. , process i

can run
    {
     t[i] = 0;    
     spinunlock( &lt[i] ); //relese lt[i]
     printf("process %ld is running\n",(long)getpid());
     t[i] = 1;  //process i is ended
     spinlock(&lt[i]);
     break;
    }   
   }
   printf("process %ld is ended\n",(long)getpid());
   break;
  }
 }

 if ( mcp > 0 )  //parentprocess , i.e. M
 {
   for ( j = 0 ; j < 3 ; j++ )
   {
    spinunlock( &l[j] ); //release process j
    while(t[j]==0)
    {  
    }
    spinlock( &l[j] );   
   }  
 } 
}

int main()
{
 init();
 return 0;
}

至此,所有操作系统课程设计的关键问题已经解决.
谢谢大家支持!



收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论


  • FnGs
    2008-10-23 21:24:58 匿名 124.114.*.*

    全班一共3个版本....


  • Hardy
    2008-10-23 21:52:45 匿名 124.114.*.*

    昏迷……看下拿走

  • 2008-10-23 23:20:08 http://eonjolily.ycool.com




  • Boss S
    2008-10-23 23:43:21 匿名 124.114.*.*

    阅,很好的。

  • 2008-10-24 12:29:40

    这个背景音乐真悲伤


  • royalshelter
    2008-10-24 15:42:04 匿名 124.114.*.*

    你说你这样弄了我还上毛机阿直接复制了..
    还有,连题目都不抄一个,谁知道怎么会事...

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定