制定交叉编译工具_Linux交叉编译工具链和模块编译

本文详细介绍了Linux交叉编译工具链,包括aarch64-poky-linux的各种工具,并展示了如何使用这些工具进行内核模块的编译。通过实例解释了如何查找内核符号、编译模块以及反汇编模块代码。此外,还提到了内核模块编译过程中的注意事项,如设置额外头文件搜索路径和使用makefile进行编译。
摘要由CSDN通过智能技术生成

所有的工具:

aarch64-poky-linux-addr2line

aarch64-poky-linux-c++filt

aarch64-poky-linux-g++

aarch64-poky-linux-gcc-nm

aarch64-poky-linux-gprof

aarch64-poky-linux-nm

aarch64-poky-linux-readelf

aarch64-poky-linux-ar

aarch64-poky-linux-cpp

aarch64-poky-linux-gcc

aarch64-poky-linux-gcc-ranlib

aarch64-poky-linux-ld

aarch64-poky-linux-objcopy

aarch64-poky-linux-size

aarch64-poky-linux-as

aarch64-poky-linux-dwp

aarch64-poky-linux-gcc-5.2.1

aarch64-poky-linux-gcov

aarch64-poky-linux-ld.bfd

aarch64-poky-linux-objdump

aarch64-poky-linux-strings

aarch64-poky-linux-c++

aarch64-poky-linux-elfedit

aarch64-poky-linux-gcc-ar

aarch64-poky-linux-gcov-tool

aarch64-poky-linux-ld.gold

aarch64-poky-linux-ranlib

aarch64-poky-linux-strip

但是编译成模块的符号并不在vmlinux中,因此下面这样使用没有效果

查找某个内核符号的位置:

$ aarch64-poky-linux-nm vmlinux | grep vmalloc_user

ffff00000819f030 T vmalloc_user

这个内核符号(地址)对应源文件的哪一行

$ aarch64-poky-linux-addr2line -e vmlinux ffff00000819f030

/media/ubuntu/work/Yocto34/source/linux/mm/vmalloc.c:1870

例子:

usbcore-y :=usb.o hub.o hcd.o urb.o message.o driver.o

usbcore-y +=config.o file.o buffer.o sysfs.o endpoint.o

usbcore-y +=devio.o notify.o generic.o quirks.o devices.o

usbcore-y +=port.o

usbcore-y +=of.o

obj-m +=usbcore.o

KDIR := /media/ubuntu/work/Yocto3_4/build/tmp/work/g6m-poky-linux/linux-renesas/4.14.35-r1/build/all:

make-C $(KDIR) M=$(PWD) modules CROSS_COMPILE=aarch64-poky-linux- ARCH=arm64

rm-f *.o *.order *.mod.c *.symvers *~clean:

rm-f *.o *.order *.mod.c *.symvers *~ *.ko

补充:

clean:make -C $(KERN_DIR) M=`pwd` modules clean #可实现自动删除rm -rf modules.order

将这个驱动编译成模块:

SRC := ehci-hcd

obj-m :=$(SRC).o

KDIR := /media/ubuntu/work/Yocto3_4/build/tmp/work/g6m-poky-linux/linux-renesas/4.14.35-r1/build

all:

#make -C $(KDIR) M=$(PWD) modules ARCH=arm64

make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=aarch64-poky-linux- ARCH=arm64 clean: rm -f *.o *.order *.mod.c *.symvers *~ *.ko

参考:Documentation/kbuild/modules.txt里面介绍了如何编译成模块。

对模块进行反汇编:

aarch64-poky-linux-objdump -D -S ehci-hcd.ko > ehci-hcd.dump

由于ehci_hcd.c编译成模块了,但是偏移还是可以正常使用的

[ 5360.731638] PC is at qh_completions+0x410/0x4e0 [ehci_hcd]

[ 5360.737134] LR is at end_unlink_async+0x18c/0x2b0 [ehci_hcd]

[ 5360.927298] [] qh_completions+0x410/0x4e0 [ehci_hcd]

[ 5360.933839] [] end_unlink_async+0x18c/0x2b0 [ehci_hcd]

[ 5360.940553] [] end_iaa_cycle+0x44/0x50 [ehci_hcd]

使用将模块进行反汇编后的代码:

0000000000002fb0 :

* Process and free completed qtds for a qh, returning URBs to drivers.

* Chases up to qh->hw_current. Returns nonzero if the caller should

* unlink qh.

*/

static unsigned qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)

{

2fb0: a9b87bfd stp x29, x30, [sp, #-128]!

2fb4: 910003fd mov x29, sp

2fb8: a90153f3 stp x19, x20, [sp, #16]

2fbc: aa0003f4 mov x20, x0

2fc0: a9025bf5 stp x21, x22, [sp, #32]

2fc4: 91006035 add x21, x1, #0x18

2fc8: a90573fb stp x27, x28, [sp, #80]

....

内核中每一个存在的符号都如0000000000002fb0 :对于显示指定的inline函数和编译器优化的inline函数,其样子如下,是没有符号地址的。

static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)

{

dma_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);

31a4: f9414280 ldr x0, [x20, #640]

31a8: aa1a03e1 mov x1, x26

31ac: f9401f42 ldr x2, [x26, #56]

31b0: 94000000 bl 0

...

对于qh_completions+0x410,只需要使用0000000000002fb0+0x410即可找出出问题的地址

Oops 信息包含以下几部分内容。

1.一段文本描述信息。

eg: “Unable to handle kernel NULL pointer dereference at virtual address 00000000” 的信息,它说明了发生的是哪类错误。

2.Oops 信息的序号。

eg: Internal error: Oops: 805 [#1] 比如是第 1 次、第 2 次等。这些信息与下面类似,中括号内的数据表示序号。

3.内核中加载的模块名称,也可能没有,以下面字样开头。

Modules linked in:

4.发生错误的 CPU 的序号,对于单处理器的系统,序号为 0,比如:

CPU: 0 Not tainted (2.6.22.6 #36)

5.发生错误时 CPU 的各个寄存器值。

6.当前进程名及进程PID

eg:Process swapper (pid: 1, stack limit = 0xc0480258) 这并不是说发生错误的是这个进程,而是表示发生错误时,当前进程是它。

错误可能发生在内核代码、驱动程序,也可能就是这个进程的错误。

7.栈信息。

8.栈回溯信息,可以从中看出函数调用关系,形式如下:

Backtrace:

[] (s3c2410fb_probe+0x0/0x560) from [] (platform_drv_

probe+0x20/0x24)

...

9.出错指令附近的指令的机器码

eg:Code: e24cb004 e24dd010 e59f34e0 e3a07000 (e5873000) (出错指令在小括号里)

要让内核出错时能够打印栈回溯信息,编译内核时要增加“-fno-omit-frame-pointer”选

项,这可以通过配置 CONFIG_FRAME_POINTER 来实现。查看内核目录下的配置文件.config,

确保 CONFIG_FRAME_POINTER 已经被定义

补充:

1.要构建外部模块,您必须具有可用的预构建内核,其中包含构建中使用的配置和头文件。

2.编译模块时生成的其它文件:

modules.order: 编译出的模块的存放路径

Module.symvers: 编译的模块通过EXPORT_SYMBOL/EXPORT_SYMBOL_GPL导出的符号,其存储语法:

3.与体系结构相关的头文件存放在arch/$(ARCH)/include/下,无关的在Linux

4.编译模块时额外指定头文件搜索路径的方法

obj-m := complex.o

ccflags-y := -I$(PWD)/include //指定额外头文件搜索路径

5.Makefile指定编译子目录 obj-y := foo/ bar/

6.modules.builtin(lib/modules下)文件列出了内核中内置的所有模块。modprobe使用它在尝试加载内置函数时不会失败。

7.编译内核:

# cp arch/arm/configs/xxxx .config

# make

8.导出内核头文件到用户空间

make headers_install ARCH=arm INSTALL_HDR_PATH=/xxx

/xxx默认是/user。

ARCH指定导出哪个体系放入头文件。make headers_install_all会导出所有体系的头文件。

要查看支持的体系结构的完整列表,请使用以下命令:ls -d include/asm-* | sed 's/.*-//

9.编译交叉平台的模块

obj-m +=leds_4412.o

KDIR= /media/ubuntu/works/tiny4412/linux-3.0.86all:make -C $(KDIR) M=$(PWD)

#rm -rf *.o *.o.cmd *.ko.cmd *.order *.symvers *.mod.c .tmp_versions

clean:rm -rf *.ko

10.编译主机平台的模块

obj-m +=leds_4412.o

all:make -C /lib/modules/`uname -r`/build M=$(PWD)rm -rf *.o *.o.cmd *.ko.cmd *.order *.symvers *.mod.c .tmp_versions

clean:rm -rf *.ko

参考:Documentation/kbuild

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值