《Linux设备驱动开发详解 A》一一3.6 工具链

简介:

本节书摘来华章计算机出版社《Linux设备驱动开发详解 A》一书中的第3章,第3.6节,作者:宋宝华 更多章节内容可以访问云栖社区“华章计算机”公众号查看。1

3.6 工具链

在Linux的编程中,通常使用GNU工具链编译Bootloader、内核和应用程序。 GNU组织维护了GCC、GDB、glibc、Binutils等,分别见于https://gcc.gnu.org/https://www.gnu.org/software/gdb/, https://www.gnu.org/software/libc/、https://www.gnu.org/software/binutils/
建立交叉工具链的过程相当烦琐,一般可以通过类似crosstool-ng这样的工具来做。crosstool-ng也采用了与内核相似的menuconfig配置方法。在官网http://www.crosstool-ng.org/上下载crosstool-ng的源代码并编译安装后,运行ct-ng menuconfig,会出现如图3.12的配置菜单。在里面我们可以选择目标机处理器型号,支持的内核版本号等。
image

图3.12  crosstool-ng的配置菜单
当然,也可以直接下载第三方编译好的、开放的、针对目标处理器的交叉工具链,如在http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/上可以下载针对ARM、MIPS、高通 Hexagon、Altera Nios II、Intel、AMD64等处理器的工具链,在http://www.linaro.org/downloads/可以下载针对ARM的工具链。
目前,在ARM Linux的开发中,人们趋向于使用Linaro(http://www.linaro.org/)工具链团队维护的ARM 工具链,它以每月一次的形式发布新的版本,编译好的可执行文件可从网址http://www.linaro.org/downloads/下载。Linaro是ARM Linux领域中最著名最具技术成就的开源组织,其会员包括ARM、Broadcom、Samsung、TI、Qualcomm等,国内的海思、中兴、全志和中国台湾的MediaTek也是它的会员。
一个典型的ARM Linux工具链包含arm-linux-gnueabihf-gcc(后续工具省略前缀)、strip、gcc、objdump、ld、gprof、nm、readelf、addr2line等。用strip 可以删除可执行文件中的符号表和调试信息等来实现缩减程序体积的目的。gprof在编译过程中在函数入口处插入计数器以收集每个函数的被调用情况和被调用次数,检查程序计数器并在分析时找出与程序计数器对应的函数来统计函数占用的时间。objdump是反汇编工具。nm则用于显示关于对象文件、可执行文件以及对象文件库里的符号信息。其中,前缀中的“hf”显示该工具链是完全的硬浮点,由于目前主流的ARM芯片都自带VFP或者NEON等浮点处理单元(FPU),所以对硬浮点的需求就更加强烈。Linux的浮点处理可以采用完全软浮点,也可以采用与软浮点兼容,但是使用FPU硬件的softfp,以及完全硬浮点。具体的ABI(Application Binary Interface,应用程序二进制接口)通过-mfloat-abi=参数指定,3种情况下的参数分别是-mfloat-abi=soft/softfp/hard。
在以前,主流的工具链采用“与软浮点兼容,但是使用FPU硬件的softfp”。 softfp使用了硬件的FPU,但是函数的参数仍然使用整型寄存器来传递,完全硬浮点则直接使用FPU的寄存器传递参数。
下面一段程序:

float mul(float a, float b)
{
        return a * b;
}
void main(void)
{
        printf("1.1 * 2.3 = %f\n", mul(1.1, 2.3));
}

对其使用arm-linux-gnueabihf-gcc编译并反汇编的结果是:
000 08394 :

8394:     b480        push  {r7}
     8396:     b083        sub  sp, #12
     8398:     af00        add  r7, sp, #0
     839a:     ed87 0a01   vstr  s0, [r7, #4](null)
     839e:     edc7 0a00   vstr  s1, [r7]
     83a2:     ed97 7a01   vldr  s14, [r7, #4](null)
     83a6:     edd7 7a00   vldr  s15, [r7]
     83aa:     ee67 7a27   vmul.f32  s15, s14, s15
     83ae:     eeb0 0a67   vmov.f32  s0, s15
     83b2:     f107 070c   add.w  r7, r7, #12
     83b6:     46bd        mov  sp, r7
     83b8:     bc80        pop  {r7}
     83ba:     4770        bx    lr

0000 83bc <main>:
     83bc:     b580        push  {r7, lr}
     83be:     af00        add  r7, sp, #0
     83c0:     ed9f 0a09   vldr  s0, [pc, #36](null)  ; 83e8 <main+0x2c>
     83c4:     eddf 0a09   vldr  s1, [pc, #36](null)  ; 83ec <main+0x30>
     83c8:     f7ff ffe4   b8394 <mul>
     83cc:     eef0 7a40   vmov.f32  s15, s0
     83d0:     eeb7 7ae7   vcvt.f64.f32  d7, s15
     83d4:     f248 4044   movw  r0, #33860  ; 0x8444
     83d8:     f2c0 0000   movt  r0, #0
     83dc:     ec53 2b17   vmov  r2, r3, d7
     83e0:     f7ff ef82   blx  82e8 <_init+0x20>
     83e4:     bd80        pop  {r7, pc}
     83e6:     bf00        nop
而使用没有“hf”前缀的arm-linux-gnueabi-gcc编译并反汇编的结果则为
000 0838c <mul>:
     838c:     b480        push  {r7}
     838e:     b083        sub  sp, #12
     8390:     af00        add  r7, sp, #0
     8392:     6078        str  r0, [r7, #4]
     8394:     6039        str  r1, [r7, #0]
     8396:     ed97 7a01   vldr  s14, [r7, #4](null)
     839a:     edd7 7a00   vldr  s15, [r7]
     839e:     ee67 7a27   vmul.f32  s15, s14, s15
     83a2:     ee17 3a90   vmov  r3, s15
     83a6:     4618        mov  r0, r3
     83a8:     f107 070c   add.w  r7, r7, #12
     83ac:     46bd        mov  sp, r7
     83ae:     bc80        pop  {r7}
     83b0:     4770        bx    lr
     83b2:     bf00        nop

000 083b4 <main>:
     83b4:     b580        push  {r7, lr}
     83b6:     af00        add  r7, sp, #0
     83b8:     4808        ldr  r0, [pc, #32]  ; (83dc <main+0x28>)
     83ba:     4909        ldr  r1, [pc, #36]  ; (83e0 <main+0x2c>)
     83bc:     f7ff ffe6   bl  838c <mul>
     83c0:     ee07 0a90   vmov  s15, r0
     83c4:     eeb7 7ae7   vcvt.f64.f32  d7, s15
     83c8:     f248 4038   movwr0, #33848    ; 0x8438
     83cc:     f2c0 0000   movtr0, #0
     83d0:     ec53 2b17   vmovr2, r3, d7
     83d4:     f7ff ef84   blx  82e0 <_init+0x20>
     83d8:     bd80        pop  {r7, pc}
     83da:     bf00        nop

关注其中加粗的行,可以看出前面的汇编使用s0和s1传递参数,后者则仍然使用ARM的r0和r1。测试显示一个含有浮点运算的程序若使用hard ABI会比softfp ABI快5%~40%,如果浮点负载重,结果可能会快200%以上。

相关文章
|
3月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
125 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
4月前
|
存储 Linux 开发工具
如何进行Linux内核开发【ChatGPT】
如何进行Linux内核开发【ChatGPT】
|
5月前
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
66 6
|
5月前
|
消息中间件 算法 Unix
Linux设备驱动开发详解1
Linux设备驱动开发详解
71 5
|
5月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
166 3
|
6月前
|
Web App开发 缓存 Linux
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
《FFmpeg开发实战》书中第10章提及轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适合生产环境。推荐使用SRS或ZLMediaKit,其中SRS是国产开源实时视频服务器,支持多种流媒体协议。本文简述在华为欧拉系统上编译安装SRS和FFmpeg的步骤,包括安装依赖、下载源码、配置、编译以及启动SRS服务。此外,还展示了如何通过FFmpeg进行RTMP推流,并使用VLC播放器测试拉流。更多FFmpeg开发内容可参考相关书籍。
156 2
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
|
6月前
|
Linux
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
《FFmpeg开发实战》书中介绍了直播的RTSP和RTMP协议,以及新协议SRT和RIST。SRT是安全可靠传输协议,RIST是可靠的互联网流传输协议,两者于2017年发布。腾讯视频云采用SRT改善推流卡顿。以下是Linux环境下为FFmpeg集成libsrt和librist的步骤:下载安装源码,配置、编译和安装。要启用这些库,需重新配置FFmpeg,添加相关选项,然后编译和安装。成功后,通过`ffmpeg -version`检查版本信息以确认启用SRT和RIST支持。详细过程可参考书中相应章节。
131 1
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
|
6月前
|
弹性计算 运维 自然语言处理
阿里云OS Copilot测评:重塑Linux运维与开发体验的智能革命
阿里云OS Copilot巧妙地将大语言模型的自然语言处理能力与操作系统团队的深厚经验相结合,支持自然语言问答、辅助命令执行等功能,为Linux用户带来了前所未有的智能运维与开发体验。
|
6月前
|
Ubuntu Linux Docker
Java演进问题之Alpine Linux创建更小的Docker镜像如何解决
Java演进问题之Alpine Linux创建更小的Docker镜像如何解决
|
6月前
|
运维 监控 大数据
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署