为ARM开发的linux驱动程序,应该怎么编译得到.o文件

为ARM开发的linux驱动程序,应该怎么编译得到.o文件,第1张

编译驱动是要和内核相关的,你的这个Mafefile是没问题,你查查你的/weke/kernel/s3c2410_kernel2418_rel那个内核有没有交叉编译过

内核里面有Makefile,所以你编译驱动的时候指定内核路径后,会用编译内核的交叉编译工具编译,然后你试一下make default

arm开发板里面应该有嵌入式linux系统,在虚拟机里安装好编译器arm-linux-gcc,对写的源文件编译后,放到嵌入式linux系统里,把嵌入式linux做成映像文件,这都是在虚拟机里做的,然后把做好的系统映像文件通过串口下载到arm开发板就ok了,多看说明书吧,厂家应该都提供的

这文章算是最近工作的备忘。

FDT是ARM

Linux最新的设备驱动程序信息表,使用FDT的内核,就不用像过去的内核那样,一个板子加一个mach的C文件,所有的设备信息可以记录在一个树状信息文件里面。

目前这方面资料比较少,我以AM335x处理器为例概括一下FDT的使用:

FDT仅仅是一个信息的目录和参数表,要使用某个功能内核中还必须有相应的驱动程序代码

FDT的源文件位置在:arch/arm/boot/dts,例如,TI的Beagle bone black,源文件是arch/arm/boot/dts/am335x_boneblackdts

FDT在make ARCH=arm的时候就会自动生成,也可用make ARCH=arm

dtbs来生成,例如TI的Beagle bone black生成的文件是arch/arm/boot/dts/am335x_boneblackdtb,这是一个二进制文件

要想新增你自定义的FDT,请修改arch/arm/boot/dts/Makefile,并在相应的Kconfig中增加config选项,例如,TI的Beagle

bone black,Kconfig的位置在arch/arm/mach-omap2/Kconfig

FDT的dtb文件由u-boot传递给内核,u-boot必须把这个文件拷贝到内核解压地址之后的某个位置,确保内核解压的时候不会覆盖,然后使用“bootm

[内核地址] - [dtb地址]”来启动内核

如果dtb文件不正确,对于310以上的内核,可能什么显示都没有,38内核,可能就显示到Uncompressing kerneldone

FDT的编写规则说明在Documentation/devicetree/bindings,不同的设备有相应的txt文件说明,其中的“compatible”可以作为关键字搜索驱动程序的源文件,例如,AM335x的GPIO,用“ti,omap4-gpio”为关键字,可以找到其代码位于drivers/gpio/gpio-omapc

FDT可以包含子文件,比如am335x_boneblackdts就包含了am33xxdtsi,am335x-bone-commondtsi

以一个例子来说明编写规则,我的板子上,I2C0上挂了一个音频CODEC,其地址是0x18,型号是TLV320AIC3104IRHBT。

先找到i2c0节点的位置,这在arch/arm/boot/dts/am33xxdtsi中:

i2c0: i2c@44e0b000

{

compatible =

"ti,omap4-i2c";

#address-cells =

<1>;

#size-cells =

<0>;

ti,hwmods =

"i2c1";

reg = <0x44e0b000

0x1000>;

interrupts =

<70>;

status =

"disabled";

};

要在这个节点上挂东西,可以直接在am33xxdtsi中挂,可以写成这样:

i2c0: i2c@44e0b000

{

compatible =

"ti,omap4-i2c";

#address-cells =

<1>;

#size-cells =

<0>;

ti,hwmods =

"i2c1";

reg = <0x44e0b000

0x1000>;

interrupts =

<70>;

status =

"okay";

tlv320aic3x: tlv320aic3x@18 {

compatible = "ti,tlv320aic3x";

reg = <0x18>;

status = "okay";

AVDD-supply = <&ldo4_reg>;

IOVDD-supply = <&ldo4_reg>;

DRVDD-supply = <&ldo4_reg>;

DVDD-supply = <&ldo4_reg>;

};

};

其中compatible字串“ti,tlv320aic3x”是在Documentation/devicetree/bindings里面全文搜索“tlv320aic”获得的,“tlv320aic3x:

tlv320aic3x@18”遵循的是“标识符:名称@地址”的格式,前面的“i2c0:

i2c@44e0b000”也是这个格式。这里的标识符可以在包含这个文件的文件或这个文件的其他位置引用,因此,可以使用arch/arm/boot/dts/am335x-boneblackdts包含arch/arm/boot/dts/am33xxdtsi,然后在am335x-boneblackdts里写:

&i2c0 {

status = "okay";

tlv320aic3x: tlv320aic3x@18 {

compatible = "ti,tlv320aic3x";

reg = <0x18>;

status = "okay";

AVDD-supply = <&ldo4_reg>;

IOVDD-supply = <&ldo4_reg>;

DRVDD-supply = <&ldo4_reg>;

DVDD-supply = <&ldo4_reg>;

};

};

&i2c0表示引用了i2c0这个标识符,然后把括号里的内容挂载到标识符下,如果属性的名字相同,例如status出现两次,前面是“disabled”后面是“okay”,以后面的为准,引用标识符的次数不受限制。

也许一开始会觉得FDT的工作过程很神秘,但你只要用compatible的字串去全文搜索一下C文件,然后仔细阅读一下,就会发现很简单,没过几分钟你就可以自定义FDT节点的属性了。反倒是这些 *** 作过程我没找到什么文档说,比较头痛,所以我把这些写出来,希望能给大家帮助。

下面说说initrd,initrd的用处是给内核一个初始的基本文件系统,用来加载内核模块之类的东西。很多人觉得嵌入式系统不需要initrd,也可以把initrd作为最终的根文件系统。我用initrd是用来校验真正的根文件系统,因为在嵌入式设备上,无法预测用户到底什么时候关机,可能会造成文件系统问题。

initrd可以用buildroot,像制作正常文件系统一样做,最后把根下的linuxrc换成一个例如下面这样的文件:

#!/bin/sh

/bin/echo Now Check SD Card

/sbin/fsckext4 /dev/mmcblk0p5

虽然Documentation/initrdtxt里面说,内核会执行initrd里面的/sbin/init,但在我用的linux-3813上,init/do_mounts_initrdc里面,执行的是/linuxrc,不知道是不是文档没有更新过来。具体的调用顺序是,kernel_init(init/mainc)

> kernel_init_freeable(init/mainc)

> prepare_namespace(init/do_mountsc)

> initrd_load(init/do_mounts_initrdc) > handle_initrd

(init/do_mounts_initrdc)。

在使用initrd的时候有几点需要注意的:

不建议在initrd上挂载别的东西,会引起未知的问题,貌似看到个文章说这个,找不到了

因为上面的这条,而且在initrd的时候,内核还没有挂载devtmpfs,因此建议使用静态设备节点,以AM335x为例(内核参数console=/dev/ttyO0,115200n8),必须的节点有:

/dev/null

/dev/console

/dev/ttyO0

这些节点可以用fakeroot之后mknod在buildroot的output/target/dev里创建,除了/dev/console,buildroot会自己创建,其他也可以写到buildroot的system/device_tabletxt里面让buildroot自动创建:

#

/dev/null

c 666 0 0

1 3

-

-

-

/dev/ttyO0 c 600

0 0 250

0

-

-

-

如果你用的是Atmel的处理器,上面的ttyO0可能是ttyS0,如果是三星的,可能是ttySAC0,而且major和minor也会不一样,请自行解决。如果你像我一样要检验SD卡,那就还必须加上SD卡的分区对应的节点。

/linuxrc可以是个程序也可以是个脚本,脚本的话,命令写绝对路径,而且记得把/linuxrc的mode改为755

使用initrd只需要用u-boot把buildroot制作的文件系统映像拷贝到内存里,然后传递initrd=[地址],[容量]这样的参数给内核,例如initrd=0x81300000,8M,最终的root参数可以不变,例如root=/dev/mmcblk0p5,这表示最终的root是SD卡上扩展分区中的第一个逻辑分区。给两个内核参数的例子:

console=ttyO0,115200n8 root=/dev/mmcblk0p5 initrd=0x81300000,8M vram=16M

consoleblank=0

console=ttyO0,115200n8 initrd=0x81300000,8M root=/dev/nfs rw

nfsroot=1921685226:/home/cdu/nfsroot

ip=1921685222:1921685226:19216851:2552552550:core335x:eth0:off

vram=16M consoleblank=0

第一个不解释了,第二个表示使用initrd,同时使用nfsroot。

最后啰嗦一句,使用initrd需要在内核配置里打开支持,这个网上的资料太多了,我就不说在哪里了。

通过ARM工程师资格证书考试后,获得由ARM公司统一发放的AAE认证证书。

ATC考试大纲:

第一阶段:Linux相关知识辅导

Linux基础知识,X-Windows基础,Ubuntu环境,Shell环境,Vi/Vim,文件管理与权限,用户管理。

第二阶段:ARM相关知识辅导

ARM系列处理器,ARM体系结构,指令及编程技术,映像文件与分散加载,gpio,MMU,常见Flash原理与设计。

第三阶段:Linux内核相关知识辅导

嵌入式开发环境建立,Linux内核基础,字符设备,中断原理与应用,调试技术,U-Boot移植及内核移植。

非常肯定的告诉你:ARM7及其以上的都可以跑Linux,ARM7以下的版本现在基本不用,或者停产。

不带内存管理单元(MMU)的用uClinux,带内存管理的别说跑Linux,跑windows ce都行。

以上就是关于为ARM开发的linux驱动程序,应该怎么编译得到.o文件全部的内容,包括:为ARM开发的linux驱动程序,应该怎么编译得到.o文件、对arm进行linux系统下载、如何在ARM Linux上使用FDT和initrd等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9323854.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存