嵌入式開(kāi)發(fā)環(huán)境的搭建實(shí)務(wù)_第1頁(yè)
嵌入式開(kāi)發(fā)環(huán)境的搭建實(shí)務(wù)_第2頁(yè)
嵌入式開(kāi)發(fā)環(huán)境的搭建實(shí)務(wù)_第3頁(yè)
嵌入式開(kāi)發(fā)環(huán)境的搭建實(shí)務(wù)_第4頁(yè)
嵌入式開(kāi)發(fā)環(huán)境的搭建實(shí)務(wù)_第5頁(yè)
已閱讀5頁(yè),還剩108頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

大連東軟信息學(xué)院嵌入式系統(tǒng)導(dǎo)論課程組嵌入式系統(tǒng)導(dǎo)論2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/313.1嵌入式開(kāi)發(fā)環(huán)境概述1.建立開(kāi)發(fā)環(huán)境2.配置開(kāi)發(fā)主機(jī),配置MINICOM3.建立引導(dǎo)裝載程序bootloader4.下載別人已經(jīng)移植好的linux操作系統(tǒng)5.建立根文件系統(tǒng)6.建立應(yīng)用程序的falsh分區(qū)7.開(kāi)發(fā)應(yīng)用程序8.燒寫(xiě)內(nèi)核、根文件系統(tǒng)、應(yīng)用程序9.發(fā)布產(chǎn)品2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/313.2Flash程序燒寫(xiě)燒寫(xiě):即利用特殊工具向開(kāi)發(fā)板中下載代碼。實(shí)例:向ARM板(裸機(jī))上燒寫(xiě)B(tài)ootLoader、內(nèi)核、根文件系統(tǒng)前提:存在目錄。./img,其下有已經(jīng)準(zhǔn)備好的各個(gè)部分軟件的映像文件(即用交叉編譯器編譯好的可執(zhí)行文件),分別為:VIVI:針對(duì)S3C2410的BootLoader映像文件zImage:經(jīng)裁剪的Linux內(nèi)核映像文件root.cramfs:根文件系統(tǒng)映像文件sjf2410:完成燒寫(xiě)的程序2023/1/313.2Flash程序燒寫(xiě)具體燒寫(xiě)步驟1.安裝JTAG驅(qū)動(dòng)程序?qū)⒄麄€(gè)giveoio目錄(JTAG驅(qū)動(dòng)所在目錄)復(fù)制到c:\WINDOWS下,并將該目錄下的giveio.sys文件復(fù)制到系統(tǒng)盤(pán)驅(qū)動(dòng)目錄下,如c:\WINDOWS\system32\drivers在控制面板中添加該驅(qū)動(dòng)程序2.設(shè)置超級(jí)終端按照波特率115300,數(shù)據(jù)位8,無(wú)奇偶校驗(yàn),停止位1,數(shù)據(jù)流控為無(wú)進(jìn)行設(shè)置3.燒寫(xiě)引導(dǎo)程序使用sjf2410程序?qū)ivi進(jìn)行第一次燒寫(xiě)vivi啟動(dòng)后,使用bonpart命令對(duì)flash進(jìn)行分區(qū)使用load命令對(duì)vivi進(jìn)行第二次燒寫(xiě)4.燒寫(xiě)內(nèi)核使用load命令對(duì)kernel進(jìn)行燒寫(xiě)5.燒寫(xiě)根文件系統(tǒng)使用load命令對(duì)rootfs進(jìn)行燒寫(xiě)2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/313.3.1BootLoader程序原理對(duì)于PC系統(tǒng),引導(dǎo)加載程序BIOS(固件程序)和位于磁盤(pán)MBR(主引導(dǎo)記錄)中系統(tǒng)引導(dǎo)程序(LILO和GRUB等)一起組成。BIOS完成硬件檢測(cè)和資源分配后,將硬盤(pán)MBR中的引導(dǎo)程序讀到系統(tǒng)的內(nèi)存中,然后將控制權(quán)交給引導(dǎo)程序。引導(dǎo)程序的主要任務(wù)就是將內(nèi)核映像從硬盤(pán)上讀到內(nèi)存中,然后跳轉(zhuǎn)到內(nèi)核的入口點(diǎn)去運(yùn)行,即開(kāi)始啟動(dòng)操作系統(tǒng)。在嵌入式系統(tǒng)中,主要使用flash作為系統(tǒng)的存儲(chǔ)煤介,很少用磁盤(pán),因此整個(gè)系統(tǒng)的加載啟動(dòng)任務(wù)就完全由引導(dǎo)程序(也稱(chēng)為Bootloader)來(lái)完成。2023/1/31就是在操作系統(tǒng)內(nèi)核運(yùn)行之前運(yùn)行的一段小程序。通過(guò)這段小程序,可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個(gè)合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。嵌入式系統(tǒng)中的bootloader概念2023/1/31Bootloader的功能1.硬件設(shè)備初始化(CPU的主頻、SDRAM、中斷、串口等)2.內(nèi)核啟動(dòng)參數(shù)3.啟動(dòng)內(nèi)核4.與主機(jī)進(jìn)行交互,從串口、USB口或者網(wǎng)絡(luò)口下載映象文件,并可以對(duì)FLASH等存儲(chǔ)設(shè)備進(jìn)行管理2023/1/31Bootloader特點(diǎn)1.依賴(lài)于硬件:每種不同的CPU體系結(jié)構(gòu)都有不同的bootloader2.bootloader還依靠具體的嵌入式板級(jí)設(shè)備的配置2023/1/31BootLoader的安裝媒介1.系統(tǒng)加電或復(fù)位后,所有的處理器通常都從某個(gè)預(yù)先安排的地址上取指令。比如,ARM在復(fù)位時(shí)從地址0x0取指。2.嵌入式系統(tǒng)中通常都有某種類(lèi)型的固態(tài)存儲(chǔ)設(shè)備(比如:ROM、EEPROM或FLASH等)被映射到這個(gè)預(yù)先安排的地址上。因此在系統(tǒng)加電后,處理器將首先執(zhí)行BootLoader程序3.Bootloader是最先被系統(tǒng)執(zhí)行的程序2023/1/31固態(tài)存儲(chǔ)設(shè)備的典型空間分配結(jié)構(gòu)2023/1/31Bootloader的燒寫(xiě)方式1.通過(guò)JTAG口2.通過(guò)以太網(wǎng)口3.通過(guò)串口4.其中前兩種方式比后一種快得多2023/1/31BootLoader的控制方式1.主機(jī)和目標(biāo)機(jī)之間一般通過(guò)串口建立連接,BootLoader軟件在執(zhí)行時(shí)通常會(huì)通過(guò)串口來(lái)進(jìn)行通訊,比如:輸出打印信息到串口,從串口讀取用戶(hù)控制字符2.也可以通過(guò)JTAG等其他接口通訊2023/1/31BootLoader的操作模式大多數(shù)BootLoader都包含兩種不同的操作模式:1.啟動(dòng)加載模式2.下載模式從最終用戶(hù)的角度看,BootLoader的作用就是用來(lái)加載操作系統(tǒng),而并不存在所謂的啟動(dòng)加載模式與下載工作模式的區(qū)別2023/1/31啟動(dòng)加載模式啟動(dòng)加載模式,稱(chēng)為“自主”(Autonomous)模式

BootLoader從目標(biāo)機(jī)上的某個(gè)固態(tài)存儲(chǔ)設(shè)備上將操作系統(tǒng)加載到RAM中運(yùn)行,整個(gè)過(guò)程并沒(méi)有用戶(hù)的介入。這種模式是BootLoader的正常工作模式,因此在嵌入式產(chǎn)品發(fā)布的時(shí)侯,BootLoader顯然必須工作在這種模式下。BootLoader的操作模式2023/1/31下載模式在下載模式下,目標(biāo)機(jī)上的BootLoader將通過(guò)串口連接或網(wǎng)絡(luò)連接等通信手段從主機(jī)下載文件,如:下載內(nèi)核映像和根文件系統(tǒng)映像等從主機(jī)下載的文件通常首先被BootLoader保存到目標(biāo)機(jī)的RAM中,然后再被BootLoader寫(xiě)到目標(biāo)機(jī)上的FLASH類(lèi)固態(tài)存儲(chǔ)設(shè)備中。這種模式通常在第一次安裝內(nèi)核與根文件系統(tǒng)時(shí)被使用;此外,以后的系統(tǒng)更新也會(huì)使用BootLoader的這種工作模式。工作于這種模式下的BootLoader通常都會(huì)向它的終端用戶(hù)提供一個(gè)簡(jiǎn)單的命令行接口。BootLoader的操作模式2023/1/31BL的典型結(jié)構(gòu)框架大多數(shù)BootLoader都分為stage1和stage2兩大部分。依賴(lài)于處理器體系結(jié)構(gòu)和板級(jí)初始化的代碼,通常都放在stage1中,用匯編語(yǔ)言實(shí)現(xiàn)而stage2則通常用C語(yǔ)言來(lái)實(shí)現(xiàn),這樣可以實(shí)現(xiàn)更復(fù)雜的功能,而且代碼會(huì)具有更好的可讀性和可移植性。

2023/1/31BootLoader的stage1通常包括以下步驟(以執(zhí)行的先后順序):硬件設(shè)備初始化。為加載BootLoader的stage2準(zhǔn)備RAM空間??截怋ootLoader的stage2到RAM空間中。設(shè)置好堆棧跳轉(zhuǎn)到stage2的C入口點(diǎn)。

BL的典型結(jié)構(gòu)框架2023/1/31BootLoader的stage2通常包括以下步驟(以執(zhí)行的先后順序):初始化本階段要使用到的硬件設(shè)備。檢測(cè)系統(tǒng)內(nèi)存映射(memorymap)。將kernel映像和根文件系統(tǒng)映像從flash上讀到RAM空間中。為內(nèi)核設(shè)置啟動(dòng)參數(shù)。調(diào)用內(nèi)核。stage2的代碼通常用C語(yǔ)言來(lái)實(shí)現(xiàn),以便于實(shí)現(xiàn)更復(fù)雜的功能和取得更好的代碼可讀性和可移植性。與普通C語(yǔ)言應(yīng)用程序不同的是,在編譯和鏈接bootloader這樣的程序時(shí),我們不能使用glibc庫(kù)中的任何支持函數(shù)。BL的典型結(jié)構(gòu)框架2023/1/313.3.2幾種流行的LinuxBootLoader1.U-Boot2.BLOB3.RedBoot4.VIVI2023/1/313.3.3S3C2410平臺(tái)上的VIVI分析vivi是由韓國(guó)Mizi公司開(kāi)發(fā)的一種BootLoader,適合于ARM9處理器,支持S3C2410UP-NETARM2410平臺(tái)的引導(dǎo)程序啟動(dòng)模式和下載模式結(jié)構(gòu)簡(jiǎn)單支持Linux內(nèi)核引導(dǎo),可以傳遞內(nèi)核參數(shù)支持分區(qū)(bon)命令行2023/1/31vivi的Stage1(文件head.S)<1>

關(guān)WATCHDOG:上電后,WATCHDOG默認(rèn)是開(kāi)著的<2>禁止所有中斷<3>初始化系統(tǒng)時(shí)鐘<4>初始化內(nèi)存控制寄存器(一共13個(gè))<5>檢查是否從掉電模式喚醒,若是,則調(diào)用WakeupStart函數(shù)進(jìn)行處理<6>點(diǎn)亮所有LED<7>

初始化UART0<8>將vivi所有代碼(包括階段1和階段2)從nandflash復(fù)制到SDRAM中<9>

跳到bootloader的階段2運(yùn)行2023/1/31vivi的Stage1(文件head.S)2023/1/31vivi的Stage2(文件main.c)1.打印vivi的信息,包括版本號(hào)等2.調(diào)用若干個(gè)初始化函數(shù)3.boot_or_vivi():判斷是否有“r”,回車(chē)或空格鍵按下,若有,則進(jìn)入vivishell;若沒(méi)有,則執(zhí)行boot命令,啟動(dòng)內(nèi)核4.boot命令執(zhí)行后,找到kernel分區(qū),找它的偏移量和大小,執(zhí)行boot_kernel()函數(shù),拷貝內(nèi)核映象5.設(shè)置linux啟動(dòng)參數(shù),打印NowBootingLinux…6.調(diào)用call_linux()函數(shù),啟動(dòng)內(nèi)核2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/313.4.1內(nèi)核的裁減ARM上的

linux內(nèi)核移植準(zhǔn)備工作1.下載linux2.6.0內(nèi)核及其關(guān)于ARM平臺(tái)的補(bǔ)丁,如:Patch-2.6.0-rmkl.gz2.給linux2.6.0打補(bǔ)丁3.準(zhǔn)備交叉編譯環(huán)境4.修改內(nèi)核目錄下的makefile文件2023/1/31Linux內(nèi)核的編譯菜單有好幾個(gè)版本:1)makeconfig:進(jìn)入命令行,可以一行一行的配置。2)makemenuconfig:開(kāi)發(fā)人員比較熟悉的menuconfig菜單。3)makexconfig:在2.4.X以及以前版本中xconfig菜單是基于TCL/TK的圖形庫(kù)的。

3.4.1內(nèi)核的裁減2023/1/312.4.X版本xconfig配置菜單:2023/1/312.4.X版本menuconfig配置菜單:2023/1/312.6.X版本xconfig配置菜單:2023/1/31內(nèi)核模塊處理方式要增加對(duì)某部分功能的支持,可以把相應(yīng)部分編譯到內(nèi)核中,也可以把該部分編譯成模塊,動(dòng)態(tài)調(diào)用。如果編譯到內(nèi)核中,在內(nèi)核啟動(dòng)時(shí)就可以自動(dòng)支持相應(yīng)部分的功能,這樣的優(yōu)點(diǎn)是方便、速度快,機(jī)器一啟動(dòng),你就可以使用這部分功能了;缺點(diǎn)是會(huì)使內(nèi)核變得龐大起來(lái),經(jīng)常使用的部分直接編譯到內(nèi)核中,比如網(wǎng)卡。如果編譯成模塊,就會(huì)生成對(duì)應(yīng)的.o文件,在使用的時(shí)候可以動(dòng)態(tài)加載,優(yōu)點(diǎn)是不會(huì)使內(nèi)核過(guò)分龐大,缺點(diǎn)是你得自己來(lái)調(diào)用這些模塊。2023/1/31在選擇相應(yīng)的配置時(shí),有三種選擇方式:Y-將該功能編譯進(jìn)內(nèi)核N-不將該功能編譯進(jìn)內(nèi)核M-將該功能編譯成可以在需要時(shí)動(dòng)態(tài)插入到內(nèi)核中的模塊2023/1/312023/1/31Linux內(nèi)核的編譯菜單有好幾個(gè)版本:1)makeconfig:進(jìn)入命令行,可以一行一行的配置。2)makemenuconfig:開(kāi)發(fā)人員比較熟悉的menuconfig菜單。3)makexconfig:在2.4.X以及以前版本中xconfig菜單是基于TCL/TK的圖形庫(kù)的。

3.4.2內(nèi)核的編譯2023/1/31(1)makeclean:清楚當(dāng)前環(huán)境(2)makedep:設(shè)置變量依賴(lài)關(guān)系(3)makezImage:編譯內(nèi)核,生成zImage編譯命令2023/1/31編譯完成的Linux內(nèi)核在哪里?./vmlinux,elf格式未壓縮內(nèi)核arch/arm/boot/compressed/vmlinux,壓縮以后的elf格式內(nèi)核,此文件是從非壓縮的內(nèi)核映像產(chǎn)生的。arch/arm/boot/zImage,可自解壓的壓縮內(nèi)核的映像文件2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/313.5根文件系統(tǒng)的構(gòu)建Linux根文件系統(tǒng)目錄結(jié)構(gòu)使用busybox生成工具集構(gòu)建根文件系統(tǒng)2023/1/31Linux根文件系統(tǒng)目錄結(jié)構(gòu)Linux根文件系統(tǒng)目錄結(jié)構(gòu)bin 必要的用戶(hù)命令(二進(jìn)制文件)*boot引導(dǎo)加載程序使用的靜態(tài)文件dev設(shè)備文件及其他特殊文件etc系統(tǒng)配置文件*home用戶(hù)主目錄lib必要的鏈接庫(kù),例如:C鏈接庫(kù)、內(nèi)核模塊mnt臨時(shí)掛載的文件系統(tǒng)的掛載點(diǎn)注:“*”目錄在嵌入式Linux上為可選的。2023/1/31Linux根文件系統(tǒng)目錄結(jié)構(gòu)*opt

附加軟件的安裝目錄proc提供內(nèi)核和進(jìn)程信息的proc文件系統(tǒng)*rootroot用戶(hù)主目錄sbin必要的系統(tǒng)管理員命令tmp臨時(shí)文件目錄usr大多數(shù)用戶(hù)使用的應(yīng)用程序和文件目錄var監(jiān)控程序和工具程序存放的可變數(shù)據(jù)Linux根文件系統(tǒng)目錄結(jié)構(gòu)2023/1/31/etc目錄--系統(tǒng)配置文件fstab 掛載文件系統(tǒng)的配置文件passwd Password文件inetd.conf Inetd守護(hù)進(jìn)程的配置文件group Group文件init.d/rcS 缺省的sysinit腳本Linux根文件系統(tǒng)目錄結(jié)構(gòu)2023/1/31使用Busybox生成工具集2023/1/31使用Busybox生成工具集2023/1/31使用Busybox生成工具集Busybox的配置和交叉編譯(1)2023/1/31使用Busybox生成工具集1.如果在開(kāi)發(fā)板上使用devfs,則需要設(shè)置GereralConfiguration選項(xiàng)[*]Supportfordevfs2.配置交叉編譯器:BuildOptions[*]DoyouwanttobuildBusyBoxwithaCrossCompiler?(/usr/local/arm/3.4.1/bin/arm-linux-)CrossCompilerprefix需要在接下來(lái)的輸入欄中輸入宿主機(jī)中交叉編譯器安裝的路徑,如“/opt/host/armv41/bin/armv41-unknown-linux-”Busybox的配置和交叉編譯(2)2023/1/31使用Busybox生成工具集3.選擇Busybox的編譯方式:BuildOptions BuildBusyBoxasastaticbinary(nosharedlibs)

缺省配置為使用鏈接庫(kù)Busybox的配置和交叉編譯(2)2023/1/31使用Busybox生成工具集配置其他工具集:ArchivalUtilities工具:tar、zip、unzip

Coreutils常用命令:basenamecatchgrpchmoddatedddfechoenvlnlsmkdirmknodmvpwdrmrmdirsleepsortsyncwcwhoami等等ConsoleUtilitiesDebianUtilitieEditors編輯命令:viawksed等FindingUtilities查找命令:findgrepxargsBusybox的配置和交叉編譯(3)2023/1/31配置其他工具集:InitUtilities[*]init[*]Supportreadinganinittabfile?[*]Supportrunninginitfromwithinaninitrd?Busybox的配置和交叉編譯(3)使用Busybox生成工具集2023/1/31配置其他工具集:Login/PasswordManagementUtilitiesLogin:gettyloginpasswdMiscellaneousUtilitiesLinuxModuleUtilitiesNetworkingUtilities網(wǎng)絡(luò)命令集:hostnameifconfiginetdnetstatpingrouteProcessUtilities進(jìn)程命令:freepssysctltopShellsshell工具:ash等

SystemLoggingUtilities日志工具:syslogdklogdLinuxSystemUtilities系統(tǒng)工具:dmesgfdiskgetoptmoremountumount使用Busybox生成工具集Busybox的配置和交叉編譯(3)2023/1/31編譯Busybox:

(1)makedep

(2)make

(3)makeinstall使用Busybox生成工具集Busybox的配置和交叉編譯(4)2023/1/31編譯生成的目錄結(jié)構(gòu)(_install

):/bin/linuxrc/sbin/usr/usr/bin/usr/sbin使用Busybox生成工具集Busybox的配置和交叉編譯(5)2023/1/31構(gòu)建根文件系統(tǒng)在_install下創(chuàng)建其它的目錄Dev:存放設(shè)備文件Proc:Lib:庫(kù)文件所在目錄Mnt:臨時(shí)掛載點(diǎn)Tmp:臨時(shí)目錄Usr:用戶(hù)目錄Var:Etc:存放系統(tǒng)設(shè)置文件目錄,在此目錄下創(chuàng)建如下文件Inittab:指定運(yùn)行級(jí)別文件Fstab:掛載文件系統(tǒng)的配置文件inetd.conf:Inetd守護(hù)進(jìn)程配置文件profile:shell配置腳本Passwd:用戶(hù)管理文件Hosts:靜態(tài)域名解析文件2023/1/31利用cramfs工具創(chuàng)建根文件系統(tǒng)映象文件mkcramfs_installroot.cramfsroot.cramfs即是最后根文件系統(tǒng)的可執(zhí)行映像文件構(gòu)建根文件系統(tǒng)2023/1/31第3章嵌入式開(kāi)發(fā)環(huán)境的搭建3.1嵌入式開(kāi)發(fā)環(huán)境概述13.2Flash程序燒寫(xiě)23.3BootLoader程序33.4內(nèi)核的裁剪的編譯43.5根文件系統(tǒng)的構(gòu)建53.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)62023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介驅(qū)動(dòng)程序是應(yīng)用程序與硬件之間的一個(gè)中間軟件層;驅(qū)動(dòng)程序應(yīng)該為應(yīng)用程序展現(xiàn)硬件的所有功能,不應(yīng)該強(qiáng)加其他的約束,對(duì)于硬件使用的權(quán)限和限制應(yīng)該由應(yīng)用程序?qū)涌刂啤?/p>

驅(qū)動(dòng)程序有時(shí)會(huì)被多個(gè)進(jìn)程同時(shí)使用,這時(shí)我們要考慮如何處理并發(fā)的問(wèn)題,就需要調(diào)用一些內(nèi)核的函數(shù)使用互斥量和鎖等機(jī)制。概念:2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介L(zhǎng)inux輸入/輸出系統(tǒng)層次結(jié)構(gòu)和功能:用戶(hù)應(yīng)用程序(設(shè)備)文件系統(tǒng)設(shè)備驅(qū)動(dòng)程序物理設(shè)備控制器輸入/輸出請(qǐng)求輸入/輸出響應(yīng)物理設(shè)備物理設(shè)備控制器2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介L(zhǎng)inux驅(qū)動(dòng)程序與外界的接口:設(shè)備驅(qū)動(dòng)程序接口具體設(shè)備驅(qū)動(dòng)程序與設(shè)備間接口系統(tǒng)初始化接口操作系統(tǒng)內(nèi)核數(shù)據(jù)結(jié)構(gòu)file_operations各設(shè)備初始化交互進(jìn)行實(shí)現(xiàn)2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31設(shè)備驅(qū)動(dòng)分類(lèi)目前Linux支持的設(shè)備驅(qū)動(dòng)大體可分為三種:字符設(shè)備(characterdevice);塊設(shè)備(blockdeivce);網(wǎng)絡(luò)接口設(shè)備(networkinterface)。設(shè)備類(lèi)型:2023/1/31設(shè)備驅(qū)動(dòng)分類(lèi)所有能夠像字節(jié)流一樣訪問(wèn)的設(shè)備比如文件等在Linux中都通過(guò)字符設(shè)備驅(qū)動(dòng)程序來(lái)實(shí)現(xiàn)。在Linux中它們也被映射為文件系統(tǒng)的一個(gè)節(jié)點(diǎn),常在/dev目錄下。應(yīng)用程序?qū)τ谧址O(shè)備的每一個(gè)I/O操作,都會(huì)直接傳遞給系統(tǒng)內(nèi)核對(duì)應(yīng)的驅(qū)動(dòng)程序;字符設(shè)備驅(qū)動(dòng)程序一般要包含open,close,read,write等幾個(gè)系統(tǒng)調(diào)用。Eg:如串口、觸摸屏、并口、虛擬控制臺(tái)、AD等。

字符設(shè)備:2023/1/31設(shè)備驅(qū)動(dòng)分類(lèi)Linux的塊設(shè)備通常是指可以容納文件系統(tǒng)的存儲(chǔ)設(shè)備。與字符設(shè)備類(lèi)似,塊設(shè)備也是通過(guò)文件系統(tǒng)來(lái)進(jìn)行訪問(wèn),它們之間的區(qū)別僅僅在于內(nèi)核內(nèi)部管理數(shù)據(jù)的方式不同。Linux中的塊設(shè)備包含整數(shù)個(gè)塊,每個(gè)塊包含2的幾次冪的字節(jié)。應(yīng)用程序?qū)τ趬K設(shè)備的操作,要經(jīng)過(guò)系統(tǒng)的緩沖區(qū)管理,間接傳遞給驅(qū)動(dòng)程序處理。Eg:諸如磁盤(pán),內(nèi)存,F(xiàn)lash等。塊設(shè)備:2023/1/31設(shè)備驅(qū)動(dòng)分類(lèi)

網(wǎng)絡(luò)接口設(shè)備比較復(fù)雜,通常它們指的是硬件設(shè)備,但有時(shí)也可是一個(gè)軟件設(shè)備(如回環(huán)接口loopback)。由內(nèi)核中網(wǎng)絡(luò)子系統(tǒng)驅(qū)動(dòng),負(fù)責(zé)發(fā)送和接收數(shù)據(jù)包,而且它并不需要了解每一項(xiàng)事務(wù)是如何映射到實(shí)際傳送的數(shù)據(jù)包的。在Linux中采用給網(wǎng)絡(luò)接口設(shè)備分配一個(gè)唯一名字的方法來(lái)訪問(wèn)該設(shè)備。Eg:eth0等。網(wǎng)絡(luò)接口設(shè)備:2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31Linux下字符型設(shè)備管理設(shè)備文件的概念來(lái)統(tǒng)一對(duì)設(shè)備的訪問(wèn)接口,在引入設(shè)備文件系統(tǒng)(devfs)之前Linux將設(shè)備文件放在/dev目錄下。設(shè)備的命名一般為設(shè)備文件名+數(shù)字或字母表示的子類(lèi),例如/dev/hda1、/dev/hda2、/dev/ttyS0等。在LINUX-2.4/2.6內(nèi)核中引入了設(shè)備文件系統(tǒng)(devfs),所有的設(shè)備文件作為一個(gè)可以?huà)煅b的文件系統(tǒng),這樣就可以被文件系統(tǒng)進(jìn)行統(tǒng)一管理,從而設(shè)備文件就可以?huà)煅b到任何需要的地方。命名規(guī)則也發(fā)生了變化,一般將主設(shè)備建立一個(gè)目錄,再將具體的子設(shè)備文件建立在此目錄下。Eg:串口1設(shè)備為:/dev/tts/0。

設(shè)備文件及設(shè)備文件系統(tǒng)概念:2023/1/31Linux下字符型設(shè)備管理傳統(tǒng)方式中的設(shè)備管理中,除了設(shè)備類(lèi)型外,內(nèi)核還需要一對(duì)稱(chēng)作主次設(shè)備號(hào)的參數(shù),才能唯一標(biāo)識(shí)一個(gè)設(shè)備。主設(shè)備號(hào)相同的設(shè)備使用相同的驅(qū)動(dòng)程序,次設(shè)備號(hào)用于區(qū)分具體設(shè)備的實(shí)例。

設(shè)備操作宏MAJOR()和MINOR()可分別用于獲取主次設(shè)備號(hào),宏MKDEV()用于將主設(shè)備號(hào)和次設(shè)備號(hào)合并為設(shè)備號(hào),這些宏定義在include/linux/kdev_t.h

中。主設(shè)備號(hào)和對(duì)應(yīng)的驅(qū)動(dòng)程序系統(tǒng)會(huì)將其記錄在/proc/devices里主設(shè)備號(hào)和次設(shè)備號(hào)(1/2):2023/1/31Linux下字符型設(shè)備管理系統(tǒng)增加一個(gè)驅(qū)動(dòng)程序就要賦予它一個(gè)主設(shè)備號(hào)。這一賦值過(guò)程在驅(qū)動(dòng)程序的初始化過(guò)程中進(jìn)行:對(duì)于字符設(shè)備:intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);主設(shè)備號(hào)和次設(shè)備號(hào)(2/2):2023/1/31Linux下字符型設(shè)備管理[/mnt/yaffs]ls /dev-lcrw------- 1rootroot 5,

1Jan 100:00consolecrw-r----- 1rootroot 1, 4Jan100:00portcrw------- 1rootroot 108, 0Jan100:00pppcrw-rw-rw-1rootroot5, 0Jan100:00ttycrw------- 1rootroot 4, 64Jan100:11ttyS0crw------- 1rootroot 4, 65Jan100:00ttyS1crw-rw-rw-1rootroot1, 5Jan100:00zero…………

查看/dev目錄下的設(shè)備的主次設(shè)備號(hào):2023/1/31Linux下字符型設(shè)備管理為該模塊建立一個(gè)設(shè)備節(jié)點(diǎn)。命令:mknod/dev/tsc2540其中/dev/ts表示我們的設(shè)備名是ts,“c”說(shuō)明它是字符設(shè)備,“254”是主設(shè)備號(hào),“0”是次設(shè)備號(hào)。一旦通過(guò)mknod創(chuàng)建了設(shè)備文件,它就一直保留下來(lái),除非我們手工刪除它。手工設(shè)備管理:2023/1/31Linux下字符型設(shè)備管理動(dòng)態(tài)分配:初始化時(shí)動(dòng)態(tài)分配設(shè)備號(hào);在Documentation/devices.txt文件中可以找到已經(jīng)靜態(tài)分配給大部分設(shè)備的列表由于許多數(shù)字已經(jīng)分配了,為新設(shè)備選擇一個(gè)唯一的號(hào)碼是很困難的如果調(diào)用register_chrdev時(shí)的major為零,函數(shù)就會(huì)選擇一個(gè)空閑號(hào)碼并做為返回值返回動(dòng)態(tài)管理(1/2):2023/1/31Linux下字符型設(shè)備管理動(dòng)態(tài)分配的主設(shè)備號(hào)不能保證總是一樣的,無(wú)法事先創(chuàng)建設(shè)備節(jié)點(diǎn)可以從/proc/devices讀取

cat/proc/devices利用腳本動(dòng)態(tài)創(chuàng)建設(shè)備文件節(jié)點(diǎn)動(dòng)態(tài)管理(2/2):2023/1/31Linux下字符型設(shè)備管理使用設(shè)備文件系統(tǒng)--devfs

:2023/1/31Linux下字符型設(shè)備管理udev完全在用戶(hù)態(tài)(userspace)工作,利用設(shè)備加入或移除時(shí)內(nèi)核所發(fā)送的hotplug事件(event)來(lái)工作。關(guān)于設(shè)備的詳細(xì)信息是由內(nèi)核輸出(export)到位于/sys的sysfs文件系統(tǒng)的。所有的設(shè)備命名策略、權(quán)限控制和事件處理都是在用戶(hù)態(tài)下完成的。與此相反,devfs是作為內(nèi)核的一部分工作的。使用設(shè)備文件系統(tǒng)--udev

:2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31Linux驅(qū)動(dòng)編譯和加載方式一種是直接編譯到內(nèi)核,當(dāng)內(nèi)核啟動(dòng)之后,新的驅(qū)動(dòng)程序隨之運(yùn)行;二是編譯為模塊,動(dòng)態(tài)加載運(yùn)行對(duì)模塊操作需要使用module-utiles:insmod將編譯的模塊直接插入內(nèi)核rmmod從內(nèi)核中卸載模塊lsmod顯示已安裝的模塊gcc編譯參數(shù):-D__KERNEL__-DMODULE

–I$(KERNELDIR_INCLUDE)在調(diào)試的過(guò)程中一般使用模塊動(dòng)態(tài)加載的方式,它的調(diào)試效率較高。當(dāng)驅(qū)動(dòng)調(diào)試完成后,在發(fā)行的過(guò)程就集成進(jìn)內(nèi)核。但編譯進(jìn)內(nèi)核是某些驅(qū)動(dòng)運(yùn)行的唯一方法。例如:console驅(qū)動(dòng),flash驅(qū)動(dòng)和對(duì)至少一種文件系統(tǒng)的支持等等。Eg:DA實(shí)驗(yàn):insmodda.o;CAN實(shí)驗(yàn):insmodcan.oLinux驅(qū)動(dòng)編譯和加載方式:2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31Linux內(nèi)核模塊結(jié)構(gòu)介紹#include<linux/module.h>//所有模塊都需要的頭文件#include<linux/init.h>//init&exit相關(guān)宏staticint__inithello_init(void){

printk("Hellomoduleinit\n");

return0;}內(nèi)核模塊的基本框架(1/2):2023/1/31Linux內(nèi)核模塊結(jié)構(gòu)介紹staticvoid__exithello_exit(void)

{

printk("Hellomoduleexit\n");

}

module_init(hello_init);

module_exit(hello_exit);

內(nèi)核模塊的基本框架(2/2):2023/1/31Linux內(nèi)核模塊結(jié)構(gòu)介紹gcc-D__KERNEL__-DMODULE-DLINUX-I/usr/src/linux2.4/include-c-ohello.ohello.cinsmod./hello.o…………rmmodhello

內(nèi)核模塊的編譯和加載:2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序在Linux內(nèi)核中往往是以模塊形式出現(xiàn)的。與應(yīng)用程序的執(zhí)行過(guò)程不同,模塊通常只是預(yù)先向內(nèi)核注冊(cè)自己,當(dāng)內(nèi)核需要時(shí)響應(yīng)請(qǐng)求。內(nèi)核模塊的編譯和加載:2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序設(shè)備驅(qū)動(dòng)程序流程圖:insmodrmmodinit_module()clean_module()模塊內(nèi)核設(shè)備功能設(shè)備注冊(cè)設(shè)備卸載用戶(hù)調(diào)用2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序重要的數(shù)據(jù)結(jié)構(gòu)—file_operations(1/3):說(shuō)明:設(shè)備驅(qū)動(dòng)程序接口:file_operations數(shù)據(jù)結(jié)構(gòu)通常所說(shuō)的設(shè)備驅(qū)動(dòng)程序接口是指結(jié)構(gòu)file_operations結(jié)構(gòu),它定義在include/linux/fs.h中。file_operations結(jié)構(gòu)是整個(gè)Linux內(nèi)核的重要數(shù)據(jù)結(jié)構(gòu)2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序重要的數(shù)據(jù)結(jié)構(gòu)—file_operations(2/3):structfile_operations{structmodule*owner;ssize_t(*read)(structfile*,char*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);int(*open)(structinode*,structfile*);int(*release)(structinode*,structfile*);//………………};

2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序重要的數(shù)據(jù)結(jié)構(gòu)—file_operations(3/3):應(yīng)用:“標(biāo)記化”方法為該結(jié)構(gòu)進(jìn)行初始化:staticstructfile_operationss3c44b0_fops={owner:THIS_MODULE,open:s3c44b0_ts_open,read:s3c44b0_ts_read,release:s3c44b0_ts_release,};2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序重要的數(shù)據(jù)結(jié)構(gòu)—file:說(shuō)明:file結(jié)構(gòu)定義在頭文件linux/fs.h中。它代表一個(gè)打開(kāi)的文件,由內(nèi)核在調(diào)用open時(shí)創(chuàng)建。并傳遞給在該文件上進(jìn)行操作的所有函數(shù),直到最后的close函數(shù)被調(diào)用。在文件的所有實(shí)例都關(guān)閉時(shí),內(nèi)核釋放這個(gè)數(shù)據(jù)結(jié)構(gòu)。注:與inode的區(qū)別,inode表示磁盤(pán)文件,而file表示一個(gè)打開(kāi)的文件2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序設(shè)備注冊(cè):驅(qū)動(dòng)程序模塊通過(guò)函數(shù)register_chrdev來(lái)完成向內(nèi)核注冊(cè)的。intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops);其中unsignedintmajor為主設(shè)備號(hào),constchar*name為設(shè)備名,structfile_operations*fops為文件操作結(jié)構(gòu)指針。2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序設(shè)備卸載:驅(qū)動(dòng)程序模塊通過(guò)函數(shù)unregister_chrdev來(lái)完成向內(nèi)核卸載的。intunregister_chrdev(unsignedintmajor,constchar*name);其中unsignedintmajor為主設(shè)備號(hào),constchar*name為設(shè)備名。2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序打開(kāi)設(shè)備:驅(qū)動(dòng)程序模塊通過(guò)函數(shù)open來(lái)完成打開(kāi)設(shè)備的。提供給驅(qū)動(dòng)程序初始化設(shè)備的能力,為后續(xù)的操作做準(zhǔn)備此外一般會(huì)遞增使用計(jì)數(shù),防止文件關(guān)閉前模塊被卸載通常情況下,open完成如下工作:遞增使用計(jì)數(shù)檢查特定設(shè)備錯(cuò)誤如果設(shè)備是首次打開(kāi),則對(duì)其進(jìn)行初始化識(shí)別次設(shè)備號(hào),如有必要,則修改f_op指針?lè)峙洳⑻顚?xiě)filp->private_data中的數(shù)據(jù)2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序釋放設(shè)備:驅(qū)動(dòng)程序模塊通過(guò)函數(shù)release來(lái)完成釋放設(shè)備的。與open正好相反釋放由open分配的filp->private_data中的數(shù)據(jù)在最后一次關(guān)閉操作時(shí)關(guān)閉設(shè)備使用計(jì)數(shù)減一2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序讀寫(xiě)設(shè)備(1/3):read函數(shù)將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序空間,write函數(shù)則將數(shù)據(jù)從應(yīng)用程序空間拷貝到內(nèi)核。ssize_tread(structfile*filp,char__user*buff,size_tcount,loff_t*offp);ssize_twrite(structfile*filp,char__user*buff,size_tcount,loff_t*offp);其中,filp是文件指針,count是請(qǐng)求傳輸?shù)臄?shù)據(jù)長(zhǎng)度。參數(shù)buff是指向用戶(hù)空間的緩存區(qū),這個(gè)緩存區(qū)或者保存要寫(xiě)入的數(shù)據(jù),或者是一個(gè)存放新讀入數(shù)據(jù)的空緩沖區(qū),最后的offp是一個(gè)指向“l(fā)ongoffsettype(長(zhǎng)偏移量類(lèi)型)”對(duì)象的指針,這個(gè)對(duì)象指明用戶(hù)在文件中進(jìn)行存取操作的位置2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序讀寫(xiě)設(shè)備(2/3):注:buff為用戶(hù)空間的地址指針,內(nèi)核代碼不能直接引用其中的內(nèi)容原因:用戶(hù)空間的指針可能是無(wú)效的,該地址可能根本就無(wú)法映射到內(nèi)核空間用戶(hù)空間的內(nèi)存可以被換出,因此可能會(huì)出現(xiàn)頁(yè)面失效的問(wèn)題從安全角度考慮解決辦法:使用內(nèi)核函數(shù)進(jìn)行數(shù)據(jù)拷貝2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序解決函數(shù):unsigned

longcopy_to_user(void*to,const

void*from,unsigned

longcount);unsigned

longcopy_from_user(void*to,const

void*from,unsigned

longcount);其中:to表示數(shù)據(jù)目的緩沖區(qū)

from表示數(shù)據(jù)源緩沖區(qū)

count表示數(shù)據(jù)長(zhǎng)度返回值:成功,返回?cái)?shù)據(jù)長(zhǎng)度

失敗,返回-EFAULT這兩個(gè)函數(shù)不僅要拷貝數(shù)據(jù),還要檢查指針有效性讀寫(xiě)設(shè)備(3/3):2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序ioctl函數(shù):int(*ioctl)(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg);其中,inode和filp對(duì)應(yīng)于應(yīng)用程序傳過(guò)來(lái)的文件描述符fd,cmd是用戶(hù)空間傳遞給驅(qū)動(dòng)程序的命令,arg為附加的命令參數(shù)讀寫(xiě)以外的I/O操作:2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序printk函數(shù):intprintk(constchar*fmt,…);其中,fmt為日志級(jí)別返回值:成功,返回1,失敗,返回-1。如:printk(KERN_DEBUG,”HereIam:%s:%i\n”,__FILE__,__LINE__);打印信息:2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序的編譯、加載及卸載:驅(qū)動(dòng)程序的編譯以demo.c為例Makefile的形式命令行的形式[root@RedHatAS~]$gcc-c-D__KERNEL__-DMODULE-I/usr/src/linux-2.4/includedemo.c-odemo.o加載驅(qū)動(dòng)[root@RedHatAS~]$insmoddemo.o卸載驅(qū)動(dòng)[root@RedHatAS~]$rmmoddemo.o2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序的編譯、加載及卸載說(shuō)明:依賴(lài)關(guān)系問(wèn)題當(dāng)模塊與內(nèi)核鏈接時(shí),insmod

會(huì)檢查模塊和當(dāng)前內(nèi)核版本是否匹配;每個(gè)內(nèi)核版本都需要特定版本的編譯器的支持,高版本的編譯器并不適合低版本的內(nèi)核;2023/1/31簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序的測(cè)試://test.c#include<stdio.h>#include<fcntl.h>#include<stdlib.h>intmain() { intfd; fd=open("/dev/demo",O_RDWR); if(fd<0) { exit(fd); } //yourcodehere read(fd,buffer,size); write(fd,buffer,size); ...... close(fd);

return0;}2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別應(yīng)用程序一般有一個(gè)main函數(shù),從頭到尾執(zhí)行一個(gè)任務(wù);驅(qū)動(dòng)程序卻不同,它沒(méi)有main函數(shù),通過(guò)使用宏module_init(初始化函數(shù)名),將初始化函數(shù)加入內(nèi)核全局初始化函數(shù)列表中。通過(guò)宏module_exit(退出處理函數(shù)名)注冊(cè)退出處理函數(shù)。驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別(1/2):2023/1/31驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別應(yīng)用程序可以和GLIBC庫(kù)連接,因此可以包含標(biāo)準(zhǔn)的頭文件,比如<stdio.h>、<stdlib.h>等,;在驅(qū)動(dòng)程序中是不能使用標(biāo)準(zhǔn)C庫(kù)的,因此不能調(diào)用所有的C庫(kù)函數(shù),只能調(diào)用內(nèi)核的函數(shù),eg:比如輸出打印函數(shù)只能使用內(nèi)核的printk函數(shù),包含的頭文件只能是內(nèi)核的頭文件,比如<linux/module.h>。驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別(2/2):2023/1/31驅(qū)動(dòng)開(kāi)發(fā)簡(jiǎn)介設(shè)備驅(qū)動(dòng)分類(lèi)Linux下字符型設(shè)備管理Linux驅(qū)動(dòng)編譯和加載方式Linux內(nèi)核模塊結(jié)構(gòu)介紹簡(jiǎn)單Linux字符型設(shè)備驅(qū)動(dòng)程序驅(qū)動(dòng)程序與應(yīng)用程序的區(qū)別字符型設(shè)備驅(qū)動(dòng)demo分析3.6驅(qū)動(dòng)程序原理與開(kāi)發(fā)2023/1/31字符型設(shè)備驅(qū)動(dòng)demo分析#include<linux/config.h>#include<linux/module.h>#include<linux/init.h>#include<linux/kernel.h>/*printk()*/#include<linux/fs.h>/*everything...*/#include<linux/errno.h>/*errorcodes*/#include<linux/types.h>/*size_t*/#include<linux/proc_fs.h>#include<linux/fcntl.h>/*O_ACCMODE*/#include<linux/poll.h>/*COPY_TO_USER*/#include<asm/system.h>/*cli(),*_flags*/#defineDEVICE_NAME "demo"#definedemo_MAJOR249#definedemo_MINOR0#defineMAX_BUF_LEN20staticchardrv_buf[20];頭文件及變量等定義:2023/1/31字符型設(shè)備驅(qū)動(dòng)demo分析static

int__initdemo_init(void) {intresult;SET_MODULE_OWNER(&demo_fops);result=register_chrdev(demo_MAJOR,"demo",&demo_fops);

if(result<0)returnresult; printk(DEVICE_NAME"initialized\n");

return0;}static

void__exitdemo_exit(void) {unregister_chrdev(demo_MAJOR,"demo"); printk(DEVICE_NAME"unloaded\n");}module_init(demo_init);module_exit(demo_

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論