當前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術圈
[導讀]關于系統(tǒng)調(diào)用,相信學習過操作系統(tǒng)的同學應該都不陌生。 那么,什么是系統(tǒng)調(diào)用? 百度的權威解釋如下: 點擊打開鏈接 由操作系統(tǒng)實現(xiàn)提供的所有系統(tǒng)調(diào)用所構成的集合即程序接口或應用編程接口(Application Programming Interface,API)。是應用程序同系統(tǒng)之間

關于系統(tǒng)調(diào)用,相信學習過操作系統(tǒng)的同學應該都不陌生。

那么,什么是系統(tǒng)調(diào)用?

百度的權威解釋如下:

點擊打開鏈接

操作系統(tǒng)實現(xiàn)提供的所有系統(tǒng)調(diào)用所構成的集合即程序接口或應用編程接口(Application Programming Interface,API)。是應用程序同系統(tǒng)之間的接口。

         那么我們編程實驗過程中使用過哪些系統(tǒng)調(diào)用呢?

         當我們要打開一個文件,對這個文件進行讀寫等操作,我們就需要使用open , read , write , lseek等基本的操作函數(shù)API,操作系統(tǒng)中就會根據(jù)我們的fd(文件句柄)找到對應的open , read , write , lseek函數(shù),在底層進行調(diào)用。

         舉一個簡單的例子:

基于tiny4412實現(xiàn)的LED驅(qū)動和應用控制

http://blog.csdn.NET/morixinguan/article/details/50619675

         我們在這個例子中就實現(xiàn)了系統(tǒng)調(diào)用:

fd = open("/dev/test-dev",O_RDWR) ;  

    if(-1 == fd)  

    {  

        printf("open fair!\n");  

        return -1 ;  

    }  

    while(1){  

        val = 0 ;  

        //寫write方法就會調(diào)用到驅(qū)動程序的led_write  

        //最后我們能看到的結果是led燈做流水燈的實現(xiàn),然后全滅,再周而復始  

        write(fd , &val , 4);  

        sleep(1);  

        val = 1 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 2 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 3 ;  

        write(fd , &val , 4);  

        sleep(1);  

        val = 5 ;  

        write(fd , &val , 4);  

        sleep(1);  

    }  

在這里,我們通過open函數(shù),打開相應的設備,這里的設備就是/dev/test-dev,然后對設備進行寫操作,操作系統(tǒng)就會通過設備節(jié)點識別我們到底調(diào)用了哪個驅(qū)動函數(shù),進而實現(xiàn)一些簡單的操作。


       通過上層的open函數(shù),內(nèi)核的初始化函數(shù)已經(jīng)對這個設備進行了注冊操作,于是通過主設備號和次設備號進而調(diào)用了相應的驅(qū)動函數(shù)led_open,接著write函數(shù)調(diào)用到底層的led_write函數(shù),具體API如下:

//啟動函數(shù)  

static __init int test_init(void)  

{  

    printk("led_init\n");  

    major = register_chrdev(major, DEV_NAME, &fops);  

    led_config = (volatile unsigned long *)ioremap(GPM4COM , 16);  

    led_dat = led_config + 1 ;    

    return 0;  

}  

//open方法,對LED燈進行初始化  

int led_open(struct inode *inode, struct file *filp)  

{  

    printk("led_open\n");//上層程序?qū)ED進行Open操作的時候會執(zhí)行這個函數(shù)  

    //先對LED的端口進行清0操作  

    *led_config &= ~(0xffff);  

    //將4個IO口16位都設置為Output輸出狀態(tài)  

    *led_config |= (0x1111);  

    return 0;  

}  

//write方法  

int led_write(struct file *filp , const char __user *buf , size_t count , loff_t *f_pos)  

{  

    int val ;   

    //注意,這里是在內(nèi)核中進行操作,我們需要使用copy_from_user這個函數(shù)將用戶態(tài)的內(nèi)容拷貝到內(nèi)核態(tài)  

    copy_from_user(&val , buf , count);   

    //以下就是當val是哪個值的時候,led就執(zhí)行相應的操作,這里不多說  

    switch(val)  

    {  

        case 0 :   

                //對狀態(tài)寄存器進行賦值,以下雷同  

                printk(KERN_EMERG"led1_on\n");  

                *led_dat &= ~0x1 ;  

                break ;  

        case 1 :  

                printk(KERN_EMERG"led2_on\n");  

                *led_dat &= ~0x2 ;  

                break ;  

        case 2 :  

                printk(KERN_EMERG"led3_on\n");  

                *led_dat &= ~0x4 ;  

                break ;  

        case 3 :  

                printk(KERN_EMERG"led4_on\n");  

                *led_dat &= ~0x8 ;   

                break ;  

        case 4 :  

                printk(KERN_EMERG"ledall_on\n");  

                *led_dat &= ~0xf ;  

                break ;  

        case 5 :   

                printk(KERN_EMERG"ledall_off\n");  

                *led_dat |= 0xf ;  

                break ;  

  

    }  

}  

上述調(diào)用過程在前面的字符設備驅(qū)動其實已經(jīng)說得很詳細就不再闡述。那么,如果我們現(xiàn)在不調(diào)用open,write,read等系統(tǒng)本身有的函數(shù),我們自己來實現(xiàn)一個,如何實現(xiàn)?


     以下我們以實現(xiàn)sys_add()系統(tǒng)調(diào)用來進行過程描述,這個API很簡單,就是通過上層調(diào)用syscall()函數(shù),傳入兩個參數(shù),使兩數(shù)相加,具體實現(xiàn)如下:

    1、在內(nèi)核源代碼根目錄找到這個文件   arch/arm/kernel/calls.S  ,打開看看:

/* 0 */ CALL(sys_restart_syscall)

CALL(sys_exit)

CALL(sys_fork_wrapper)

CALL(sys_read)

CALL(sys_write)

/* 5 */ CALL(sys_open)

CALL(sys_close)

....

在這個文件里,聲明我們系統(tǒng)需要調(diào)用的API,我們把相應的添加到最后面:


    我們把我們需要的添加到最后:
    /*376*/ CALL(sys_add)     這里376表示系統(tǒng)調(diào)用號,第376號

   2、在內(nèi)核源代碼根目錄找到這個文件   arch/arm/include/asm/unistd.h,打開看看:

/*

 * This file contains the system call numbers.

 */


#define __NR_restart_syscall (__NR_SYSCALL_BASE+  0)

#define __NR_exit (__NR_SYSCALL_BASE+  1)

#define __NR_fork (__NR_SYSCALL_BASE+  2)

#define __NR_read (__NR_SYSCALL_BASE+  3)

#define __NR_write (__NR_SYSCALL_BASE+  4)

#define __NR_open (__NR_SYSCALL_BASE+  5)

#define __NR_close (__NR_SYSCALL_BASE+  6)

....

在__NR這個標號375號后面添加:


#define __NR_add (__NR_SYSCALL_BASE+376)

  3、在內(nèi)核源代碼根目錄找到這個文件   arch/arm/kernel/sys_arm.c , 打開看看


在文件的最后添加:

asmlinkage long sys_add(int a, int b)

{

return a+b;

}

這樣,我們就完成了對底層系統(tǒng)調(diào)用的實現(xiàn),接下來,我們來驗證我們寫的這個程序的結果,看看對不對。

具體如下:

為了方便驗證,這里就不再寫應用程序,有興趣可以自己去驗證,也很簡單。我們這里采用的還是以驅(qū)動的形式進行加載。

步驟如下:

1、先在driver目錄下創(chuàng)建一個目錄:yyx_syscall

依次創(chuàng)建syscall_add.c  Makefile

往syscall_add.c添加代碼:

#include<linux/kernel.h>

#include<linux/module.h>

#include<linux/sched.h>

#include<asm/uaccess.h>

#include<linux/compiler.h>

#include<linux/linkage.h>

#include<linux/types.h>

#include<linux/unistd.h>


//在linux內(nèi)核根目錄下找到System.map中sys_add的地址

#define SYS_CALL_ADD_TB 0xc004e30c  

//這里通過一個指針去獲取系統(tǒng)函數(shù)的入口地址

unsigned long *sys_call_table_add = (unsigned long*)SYS_CALL_ADD_TB; 

asmlinkage long sys_add(int a , int b) ; //在這里定義一個函數(shù)


int __init init_addsyscall(void)

{

int ret ;

sys_call_table_add[376] = sys_add(1,2); //上面定義的這個函數(shù)作為參數(shù)傳遞給這個指針

ret = sys_call_table_add[376] ;//獲取到了參數(shù)

        printk("System call add loaded ret:%d\n",ret); //執(zhí)行結果

        return 0;

}


void __exit exit_addsyscall(void)

{

        printk("System call unlodaded\n");

}


module_init(init_addsyscall);

module_exit(exit_addsyscall);

MODULE_LICENSE("GPL");

Makefile內(nèi)容如下:


obj-y += syscall_add.o


然后回到內(nèi)核的根目錄下:

make -j4

將編譯生成的zImage下載到板子上,運行,我們可以看到串口中打印了相應的數(shù)據(jù),是數(shù)字3,也就是1+2的結果,驗證成功。



免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉