u-boot的任務是啟動內核,內核的任務是啟動應用程序 ,應用程序會涉及很多文件和硬件操作(當然不會直接操作硬件),比如讀寫文件,點燈、獲取按鍵值。
比如對於控制led燈的用戶程序與驅動程序,最簡單的實現方法是:
應用程序中需要打開led燈,就需要open函數,在內核中的驅動程序中也有對應的led_open函數,這個led_open函數就是用來負責初始化led的引腳功能,應用程序中要調用read函數讀取led燈的狀態,內核中的驅動程序也有led_read函數。這是應用程序與內核中驅動程序一種最簡單的對應方式.
那么應用程序中的open、read函數最終怎樣調用到驅動程序中的led_open、led_read呢,中間有哪些東西?
在linux中共有4層軟件,如下圖:
應用程序:就是被調用的那些庫函數,例如open、read、write... ...
C庫(系統調用):其中的其實就是實現open、read這些函數來調用swi val 指令進入內核(函數不同val值都會不同)
內核: 內核根據swi后面不同的值去調用VFS中的system_open/system_read/ system_write等異常處理函數 找到相應的驅動程序(VFS:virtual file system 虛擬文件系統)
例如:
int main() { int fd1 fd2; int val=1; fd1 = open(“/dev/led”,O_RDWR); //打開led write(fd1, &val, 4); fd2 = open(“hello.txt”,O_RDWR); //打開文本 write(fd2, &val, 4); }
上面的應用程序主要實現點燈與打開文本文件,都是用的同樣的函數。但是點燈與打開文本文件的行為顯然不一樣。那么誰來實現這些不一樣的行為呢?
對於LED燈,有led_open驅動程序。對於文本文件存在於flash設備上,也有對於的驅動程序。system_open、system_read最終會根據打開的不同文件,找到底層的不同驅動程序,然后調用驅動程序中的硬件操作函數,比如led_open來實現對具體硬件設備的操作。
這就是整個的字符設備驅動程序框架。
例如LED,如下圖:
在應用層應用程序中有open、read、write
同樣,在驅動程序中也對應有led_open、led_read、led_write
剩下的就是驅動框架了。