Windforce » 日志 » 操作系统课程设计全攻略
操作系统课程设计全攻略
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( <[i] ); //relese lt[i]
printf("process %ld is running\n",(long)getpid());
t[i] = 1; //process i is ended
spinlock(<[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;
}
至此,所有操作系统课程设计的关键问题已经解决.
谢谢大家支持!
最新评论
-
2008-10-23 21:24:58 匿名 124.114.*.*
全班一共3个版本....
-
2008-10-23 21:52:45 匿名 124.114.*.*
昏迷……看下拿走
-
2008-10-23 23:20:08 http://eonjolily.ycool.com
☆


-
2008-10-23 23:43:21 匿名 124.114.*.*
阅,很好的。 -
2008-10-24 12:29:40
这个背景音乐真悲伤
-
2008-10-24 15:42:04 匿名 124.114.*.*
你说你这样弄了我还上毛机阿直接复制了..
还有,连题目都不抄一个,谁知道怎么会事...


