nios软核cpu中架构类shell的一种解决方式『linux 系统函数调用的

nios软核cpu中架构类shell的一种解决方式『linux 系统函数调用的方法』

分类:

在nios中要实现一个类shell的交互系统,用户在终端可以通过命令调用系统函数。 想到linus当年在写下系统函数调用时,,其实基于的思想是一样的,就是查表,每一种系统函数都对应一种中断服务号,然后通过0x80系统调用进入内核,然后查表,这里就可以找到对应的内核系统函数,回顾一下linus是怎么做到的。 就以系统函数open为例子

int open(const char * filename, int flag, …){ register int res; va_list arg; va_start(arg,flag); __asm__(“int $0x80″ :”=a” (res) :”0″ (__NR_open),”b” (filename),”c” (flag), “d” (va_arg(arg,int))); if (res>=0) return res; errno = -res; return -1;}

这个open函数是一个变参函数,对变参函数的研究在前面用一片博文已经讲过,不多说。 主要看着这几个重要代码

“int $0x80″:”0” (__NR_open)

这是软件调用,__NR_open是传入的参数,是一个宏定义

#define __NR_open 5

对与0x80这个中断号,需要在找到中断向量表其对应的中断向量, 在调度初始化函数sched.c中有

set_system_gate(0x80,&system_call);

就是对应中断0x80的中断向量为system_call,所以这就是为什么大家叫0x80是系统函数调用中断号了。

看看systen_call

_system_call: pushl %eax # save the orig_eax pushl %edx pushl %ecx # push %ebx,%ecx,%edx as parameters pushl %ebx # to the system call movl $0x10,%edx # set up ds,es to kernel space mov %dx,%ds mov %dx,%es movl $0x17,%edx # fs points to local data space mov %dx,%fs cmpl _NR_syscalls,%eax jae bad_sys_call call _sys_call_table(,%eax,4) pushl %eax

看重要的几句代码

cmpl _NR_syscalls,%eax call _sys_call_table(,%eax,4)

第一句对比传进来的参数,以确定需要调用什么系统函数 第二句调用相应的系统函数

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending, sys_sethostname,sys_setrlimit, sys_getrlimit, sys_getrusage, sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups, sys_select, sys_symlink,sys_lstat, sys_readlink, sys_uselib };

这其实是一个数组,其中typedef int (*fn_ptr)(); 所以是函数指针数组,中断服务号作为数组的下标查表, 上面知道open的服务号是5,则 sys_call_table[5]确实对应着函数 sys_open的地址。 所以这样就完成的整个一个从用户到内核的调用,如图所示

所以在 nois中开发一个类shell的交互系统,是可以借鉴这个模型的,在对这个模型简化一下,这里面最重要的是那个表(函数指针数组),在nios是是单线程跑的,所以中断这块可以去掉,利用查询的方式来完成。还有就是如何将用户输入的命令和系统命令匹配起来,是否还是想linus一样采用数字来对应,但是实际用户输入的是字符串,所以是否字节是字符串匹配,既然是字符串就不可以是用数组下标的方式了,想到c++中的map类;这是一种关联变量,为此可以写一个结构体,也可以达到这种效果。

typedef struct key{用户命令字符串;用户参数;命令处理函数;}KEY;

实际这就是一个命令所有相关的东西,然后用数组将这些命令结构体存储起来。

;

通过对比每个结构体的第一个成员,以确定命令然后调用命令函数。

最终实现的初始化cmd_table如下

版权声明:本文为博主原创文章,未经博主允许不得转载。

上一篇小编程题–解决一维迷宫问题

顶1踩0

即使没有收获的希望也心平气和的继续。

nios软核cpu中架构类shell的一种解决方式『linux 系统函数调用的

相关文章:

你感兴趣的文章:

标签云: