nios軟核cpu中架構類shell的一種解決方式

來源:互聯網
上載者:User

標籤:

在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: push %ds push %es push %fs 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;

實際這就是一個命令所有相關的東西,然後用數組將這些命令結構體儲存起來。

KEY  cmd_table[];

通過對比每個結構體的第一個成員,以確定命令然後調用命令函數。

最終實現的初始化cmd_table如下

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

nios軟核cpu中架構類shell的一種解決方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.