基于ARM体系结构的嵌入式开发(1)-----移植第一个驱动程序
本文是基于s3c2440,arm9内核的linux开发
一.选用arm开发板;S3C2440 (天嵌的那款)
买来的板子已经移植好uboot,linux内核。所以先用secureCRT链接开发板,然后执行命令 uname -a
Linux EmbedSky 2.6.30.4-EmbedSky
二.PC机装上linux操作系统
1)安装虚拟机:vmware
2)安装操作系统:fedore 14(界面非常友好)
这两个软件下载都很容易的
3)下载linux内核 (版本要与arm上移植的相同) 内核下载
4)将内核压缩文件复制到fedore14 操作系统,在终端输入命令:
tar xjvf linux-2.6.30.4_20100531.tar.bz2 -C/linux-2.6.30
-C表示解压后的目标文件夹
三.熟悉linux界面
1.熟悉linux的常用命令
上面 tar xjvf linux-2.6.30.4_20100531.tar.bz2 -C/linux-2.6.30 就是解压文件
linux 命令格式为 命令+[选项的方式]
了解vi编辑器,这是linux系统下的一种常用的文本编辑方式
详细的命令及vi的介绍见 linux命令详解
2.了解shell
这个可以暂时不看,有兴趣的同学可以参考 shell参考资料
3.gcc编译器
和学习其他语言,使用编译器是一样的道理,将高级语言编译为硬件能明白的语言。
这里值得一提的是交叉编译器,采用的是ARM-LINUX-gcc 。因为arm板或者说其他嵌入式平台,其本身资源很少,没有足够的资源去运行编译开发工具,调试工具。所以我们要在本机上编译,然后移植到嵌入式平台中执行
。有关ARM-linux-gcc版本和linux内核版本问题将在下文提到
eg.现在终端输入vi test-1.c ,进入vi编辑器
#include<stdio.h>
void main()
{
printf(“hello,world!”);
}
esc :wq 保存退出然后在终端下执行gcc test_1.c -o test_1
然后执行 ./test-1 即可打印出hello,world!
4.关于smb(window与linux之间的通信) nfs(linux与linux之间的通信) 网上资料很多,就不提了。对于本实验,也用不到上述服务
具体可参考这篇 配置smb和nfs
四.移植第一个驱动程序
这是嵌入式开发的基本架构,右侧只是举了个例子。
linux的驱动开发有两种方法:1.直接编译到内核,再运行新的内核来测试
2.编译模块的方式,单独加载进行调试
1)由于是第一个驱动程序,所以首先必须要编译内核。
编译内核:终端下进入linux内核目录 ,
#make menuconfig 进入 load an alternate configuration file
输入 arch/arm/configs/s3c2440_defconfig
ok
在system type 选单中s3c24**中只选中smdk2410/a9m2410,smdk2440, smdk2440 with s3c2440 cpu mode
保存配置文件为.config
终端下输入#make zImage (如果要移植内核到开发板,可以以JTAG方式将生成的zimage移植到开发板上)
2)移植驱动程序
将厂家提供的模块EmbedSky_gpio.c复制到内核目录的drivers/char 目录
1、修改同目录下的Kconfig
添加下面代码 [此选项将会在内核配置界面显示]
config TQ2440_GPIO_TEST
tristate "EmbedSky SKY2440/TQ2440 Board GPIO Test(control LED)"
depends on ARCH_S3C2440
default y if ARCH_S3C2440
help
GPIO control for EmbedSky SKY2440/TQ2440 Board.
2、修改同目录下的Makefile
obj-$(CONFIG_TQ2440_GPIO_TEST)+= EmbedSky_gpio.o
3、配置内核 DEVICE drivers -character devices 选中
4、终端输入
#make SUBDIR=drivers/char modules
或者另外为EmbedSky_gpio.c建一个文件,编写相应的Makefile
obj-m :=EmbedSky_gpio.o
KERNELDIR := /linux-2.6.30/linux-2.6.30.4/ #指向内核目录
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers
.PHONY: all clean
make.生成.ko文件
5.insmod 加载到内核模块
这时出现个错误
insmod: errorinserting 'EmbedSky_gpio.ko': -1 Invalid module format
查看日志 #cat /var/log/messages |tail
显示
Nov 8 19:11:06 localhost smbd[5242]: [2012/11/0819:11:06.786765, 0]printing/print_cups.c:109(cups_connect)
Nov 8 19:11:06 localhost smbd[5242]: Unable to connect to CUPS serverlocalhost:631 - Connection refused
Nov 8 19:11:06 localhost smbd[1790]: [2012/11/0819:11:06.787232, 0]printing/print_cups.c:468(cups_async_callback)
Nov 8 19:11:06 localhost smbd[1790]: failed to retrieve printer list:NT_STATUS_UNSUCCESSFUL
都是smb什么的。这应该和smb没什么关系啊
根据意思,是模块不匹配
网上百度了一下,发现犯这个错误的人真是不少,找了些文章看了下,发现都是说要加载的模块指定的内核版本与当前的内核版本不一致。需要修改成一致。
这里要说明下有关版本的问题:
首先得明确你是要基于什么开发的,PC 机的linux下,还是嵌入式平台。我之前已经说过,我是基于arm体系结构,我arm上移植了linux操作系统,我现在要基于ARM上的linux操作系统开发,我只是在PC机的linux系统下开发而已。所以我要加载的模块指定的内核版本和我linux系统版本没多大关系,也不需要匹配的。所以网友提高的错误应该不是我的错误。我将.ko文件复制,用U盘挂载到arm上。执行insmod 命令时提示错误
version magic '2.6.30.4 mod_unload ARMv4 ' should be '2.6.30.4-EmbedSky mod_unload ARMv4
为什么linux内核版本都是2.6.30 ,还是提示有错误呢。后来想到我这是天嵌的平台,可能有别于其他平台。
所以重新配置内核,在Local version 中加入 -EmbedSky 退出保存为.config 然后重新编译内核。编译模块,重新加载,最后解决了问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?