瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內(nèi)置獨(dú)立NPU,可用于輕量級(jí)人工智能應(yīng)用。RK3568 支持安卓 11 和 linux 系統(tǒng),主要面向物聯(lián)網(wǎng)網(wǎng)關(guān)、NVR 存儲(chǔ)、工控平板、工業(yè)檢測(cè)、工控盒、卡拉 OK、云終端、車載中控等行業(yè)。
迅為RK3568開發(fā)板:
?
進(jìn)階5 自定義實(shí)現(xiàn)insmod命令實(shí)驗(yàn)
5.1 實(shí)驗(yàn)程序的編寫
在本章節(jié)將會(huì)實(shí)現(xiàn)第二種方法實(shí)現(xiàn)insmod命令。
5.1.1 驅(qū)動(dòng)程序編寫
本實(shí)驗(yàn)對(duì)應(yīng)的網(wǎng)盤路徑為:iTOP-RK3568開發(fā)板【底板V1.7版本】\03_【iTOP-RK3568開發(fā)板】指南教程\02_Linux驅(qū)動(dòng)配套資料\04_Linux驅(qū)動(dòng)例程\52_module02\01_module。
編寫完成的helloworld.c代碼如下所示。
#include
#include
static int __init helloworld_init(void) //驅(qū)動(dòng)入口函數(shù)
{
dump_stack();
return 0;
}
static void __exit helloworld_exit(void) //驅(qū)動(dòng)出口函數(shù)
{
printk(KERN_EMERG "helloworld_exit\r\n");
}
module_init(helloworld_init); //注冊(cè)入口函數(shù)
module_exit(helloworld_exit); //注冊(cè)出口函數(shù)
MODULE_LICENSE("GPL v2"); //同意 GPL 開源協(xié)議
MODULE_AUTHOR("topeet"); //作者信息
該驅(qū)動(dòng)程序就是最簡單的helloworld驅(qū)動(dòng)程序,只是在第6行添加了dump_stack()函數(shù),用來在內(nèi)核中輸出當(dāng)前調(diào)用堆棧信息,在這里使用該函數(shù)的目的是驗(yàn)證在app中的init_module系統(tǒng)調(diào)用是否生效。
5.1.2 編寫測(cè)試 APP
本應(yīng)用程序?qū)?yīng)的網(wǎng)盤路徑為:iTOP-RK3568開發(fā)板【底板V1.7版本】\03_【iTOP-RK3568開發(fā)板】指南教程\02_Linux驅(qū)動(dòng)配套資料\04_Linux驅(qū)動(dòng)例程\52_module02\02_app。
編寫完成的應(yīng)用程序app.c代碼如下所示:
#include
#include
#include
#include
#include
#include
#include
#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
int main(int argc, char **argv)
{
int fd; // 文件描述符
int ret; // 返回值
struct stat statbuf; // 存儲(chǔ)文件信息的結(jié)構(gòu)體
size_t image_size; // 文件大小
char *image; // 文件內(nèi)容緩沖區(qū)
fd = open(argv[1], O_RDONLY | __O_CLOEXEC); // 以只讀方式打開文件
if (fd < 0)
{
printf("open error \n"); // 打開文件失敗
return -1;
}
fstat(fd, &statbuf); // 獲取文件信息
image_size = statbuf.st_size; // 獲取文件大小
image = malloc(image_size); // 為文件內(nèi)容分配內(nèi)存空間
read(fd, image, image_size); // 讀取文件內(nèi)容到緩沖區(qū)
ret = init_module(image, image_size, ""); // 調(diào)用系統(tǒng)調(diào)用初始化內(nèi)核模塊
if (ret < 0)
{
printf("error \n"); // 內(nèi)核模塊初始化失敗
}
else
{
printf("ok \n"); // 內(nèi)核模塊初始化成功
}
free(image); // 釋放內(nèi)存空間
return ret; // 返回結(jié)果
}
該應(yīng)用程序的重點(diǎn)在30行,使用init_module系統(tǒng)調(diào)用加載模塊到內(nèi)核。
5.2運(yùn)行測(cè)試
5.2.1 編譯驅(qū)動(dòng)程序
在上一小節(jié)中的helloworld.c代碼同一目錄下創(chuàng)建 Makefile 文件,Makefile 文件內(nèi)容如下所示:
export ARCH=arm64#設(shè)置平臺(tái)架構(gòu)
export CROSS_COMPILE=aarch64-linux-gnu-#交叉編譯器前綴
obj-m += helloworld.o #此處要和你的驅(qū)動(dòng)源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel #這里是你的內(nèi)核目錄
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules #make操作
clean:
make -C $(KDIR) M=$(PWD) clean #make clean操作
對(duì)于Makefile的內(nèi)容注釋已在上圖添加,保存退出之后,來到存放helloworld.c和Makefile文件目錄下,如下圖(圖5-1)所示:
然后使用命令“make”進(jìn)行驅(qū)動(dòng)的編譯,編譯完成:
編譯完生成platform_led.ko目標(biāo)文件:
至此驅(qū)動(dòng)模塊就編譯成功了。
5.2.2 編譯應(yīng)用程序
下面進(jìn)行應(yīng)用程序編譯,因?yàn)闇y(cè)試APP是要在開發(fā)板上運(yùn)行的,所以需要aarch64-linux-gnu-gcc來編譯,輸入以下命令,編譯完成以后會(huì)生成一個(gè)app的可執(zhí)行程序,如下圖(圖141-4)所示:
aarch64-linux-gnu-gcc myinsmod.c
下面進(jìn)行驅(qū)動(dòng)程序的測(cè)試。
5.2.3運(yùn)行測(cè)試
本次測(cè)試要使用上面編譯的helloworld.ko驅(qū)動(dòng)文件和a.out可執(zhí)行文件,所以需要先將兩個(gè)要用到的文件拷貝到開發(fā)板上。
開發(fā)板啟動(dòng)之后,使用以下命令加載helloworld.ko驅(qū)動(dòng),如下圖所示:
./a.out helloworld.ko
dump_stack函數(shù)會(huì)打印調(diào)用的一系列函數(shù),這些函數(shù)的具體調(diào)用已經(jīng)在進(jìn)階第一章講解過了,這里的重點(diǎn)為紅色框中的倒數(shù)第二行,調(diào)用了init_module函數(shù)加載了helloworld驅(qū)動(dòng)。
然后繼續(xù)使用以下命令查看驅(qū)動(dòng)的加載情況,打印如下圖(141-6)所示:
lsmod
可以看到helloworld驅(qū)動(dòng)成功加載上了,最后可以使用以下命令進(jìn)行驅(qū)動(dòng)的卸載,
rmmod
至此,內(nèi)核是如何運(yùn)行KO文件的_insmod實(shí)驗(yàn)就完成了。
-
處理器
+關(guān)注
關(guān)注
68文章
18924瀏覽量
227204 -
芯片
+關(guān)注
關(guān)注
450文章
49631瀏覽量
417113 -
驅(qū)動(dòng)
+關(guān)注
關(guān)注
12文章
1788瀏覽量
84896 -
RK3568
+關(guān)注
關(guān)注
4文章
479瀏覽量
4716
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論