嵌入式Linux开发:开源组件、第三方库与许可证详解

嵌入式Linux开发:开源组件、第三方库与许可证详解(纯新手向)

本章内容:学习嵌入式Linux能复用哪些现成的开源组件?如何选择?许可证是什么?GPL和LGPL有什么区别?嵌入式设备上常用的网络、多媒体、图形、Web等软件有哪些?------ 结尾附面试必考题。


文章目录

(一)嵌入式系统可用的开源组件分类

  • 开源组件
  • Target(目标)设备工具
    • 网络
    • 系统实用程序
    • 编程语言
    • 音频、视频 和 多媒体
    • 图形套件
    • 数据库
    • 网络浏览器
  • 嵌入式系统构建语言

讲解

做嵌入式Linux产品,不需要从头写所有代码。开源社区已经准备好了大量可以直接复用的软件组件,你只需要把它们集成到你的系统中。

这些组件覆盖了几乎所有功能领域:

  • 网络:Web服务器、SSH、DNS、防火墙、NTP等。
  • 系统实用程序:文件处理、进程管理、日志系统、启动脚本等(BusyBox就是典型)。
  • 编程语言:Python、Lua、Shell、PHP、Perl等解释器,让你在产品里跑脚本或快速开发应用。
  • 音频、视频和多媒体:编解码库(MP3、H.264)、流媒体框架(GStreamer)、音频服务器(ALSA)。
  • 图形套件 :图形界面库(Qt、GTK)、显示服务器(X.Org、Wayland)。
  • 数据库:SQLite(轻量级)、MySQL/PostgreSQL(重型,少见于嵌入式)等。
  • 网络浏览器:WebKit引擎,可用来做全屏浏览器应用或渲染HTML。

嵌入式系统构建语言 指的是Buildroot的.mk文件、Yocto的.bb/.bbappend配方、OpenWrt的Makefile等------它们是用脚本语言(主要是Make、Shell、Python)描述如何从源码编译出这些组件并打包进镜像。

初学者理解:你以后的工作很大一部分就是"选组件、配组件、编译组件、打包组件"。不需要自己实现一个Web服务器,直接用lighttpd;不需要自己写MP3解码,直接用libmad。站在巨人的肩膀上。


(二)为什么可以复用开源组件?以及复用中的挑战

  • 第三方库和应用程序
    • 嵌入式 Linux 的优势之一是可以在其产品中利用广泛的第三方库和应用程序
      • 它们是免费提供的,可以自由分发的,并且由于它们的开源特性,它们可以根据项目的需要进行分析和修改
    • 然而,有效地重复使用这些组件并不总是那么容易。一个必须:
      • 找到这些组件
      • 选择最合适的
      • 交叉编译
      • 将它们集成到嵌入式系统和其他应用程序中
  • 查找现有组件
    • 查看嵌入式 Linux 构建系统打包的软件列表
      • 通常选择这些是因为它们适用于嵌入式系统
      • 看看其他嵌入式 Linux 产品,看看它们的组件是什么。
      • 询问社区或您最喜欢的搜索引擎

讲解

解释了"为什么能用"以及"为什么有时麻烦"。

为什么能用

  • 绝大多数开源组件遵循自由软件许可证,允许免费使用、修改、重新分发。
  • 你可以深入源码,修复bug、裁剪功能、优化性能。
  • 你不用重复造轮子,节省几个月甚至几年的开发时间。

为什么有时麻烦

  • 找到合适的组件并不简单------网络上同名项目很多,质量参差不齐。
  • 你得从多个候选里选出最稳定的、最活跃的、最符合你需求的。
  • 所有组件都需要交叉编译(ARM平台上运行,你需要在PC上编译)。
  • 编译完成后,还要集成到根文件系统,确保库路径、依赖关系都正确。

如何查找组件

  • 查看Buildroot/Yocto/OpenWrt的包列表(这些工具已经帮你筛选了嵌入式友好的软件)。
  • 参考同类型产品的开源部分(比如看小米路由器用了哪些开源项目)。
  • 直接搜 embedded http serverlightweight ssh for arm 等关键词。

初学者建议 :先学习使用Buildroot或Yocto,它们内置了数千个组件的配置选项,你只需要 make menuconfig 打个勾,构建系统就会自动下载、交叉编译、安装到根文件系统。等熟悉了,再考虑手动交叉编译单个组件。


(三)选择开源组件时的四个注意点

并非所有的自由软件组件都可以在开发中重用。必须注意:

  • Vitality(开发者和用户社区的活力)。这种活力保证了组件的长期维护,以及相对良好的支持。它可以通过查看邮件列表流量和版本控制系统活动来衡量。
  • Quality(组件的质量)。通常,如果某个组件已经通过嵌入式构建系统可用,并且具有动态的用户社区,则可能意味着质量相对较好。
  • License(许可证)。组件的许可证必须与您的许可限制相匹配。例如,不能在专有应用程序中使用 GPL 库。
  • Technical requirements(技术要求)。当然,组件必须符合您的技术要求。如果缺少某个功能,您可以改进现有组件!

讲解

不是所有看上去"能用"的开源组件都适合你的项目。你需要从四个维度评估:

1. 活力(Vitality):一个三年没更新、邮件列表全是垃圾广告的项目,很可能有未修复的bug,无人维护,未来也不支持新内核。怎么判断?看GitHub的提交频率、issue响应速度、邮件列表活跃度。

2. 质量(Quality):代码规范、有单元测试、有很多实际用户。如果Buildroot或Yocto收录了这个组件,说明它至少能成功交叉编译并且被很多人用过,质量相对有保障。

3. 许可证(License) :这是最容易踩坑的地方。如果你的产品是闭源的(大多数商业产品),那么绝对不能使用GPL许可证的库(除非你愿意开源整个产品)。后文会详细讲。

4. 技术要求(Technical requirements):这个组件是否满足你的功能?它占用的内存、CPU、存储是否在可接受范围?如果现有组件缺一两个功能,你可以自己修改源码加进去,这是开源的优势。

初学者重点:第一个项目尽量选"在Buildroot里直接打勾就能用"的组件。它们已经过了考验。自己随便从GitHub找一个星标少的项目,很可能交叉编译时各种依赖缺失,让你崩溃。


(四)自由软件的四大自由

  • 拥有自由软件许可的所有软件给予所有用户四项自由
    • 自由度0:无论用户出于何种目的,必须可以按照用户意愿,自由地运行该软件。
    • 自由度1:用户可以自由地学习并修改该软件,以此来帮助用户完成用户自己的计算。作为前提,用户必须可以访问到该软件的源代码。
    • 自由度2:用户可以自由地分发该软件的拷贝,这样就可以助人。
    • 自由度3:用户可以自由地分发该软件修改后的拷贝。借此,用户可以把改进后的软件分享给整个社区令他人也从中受益。作为前提,用户必须可以访问到该软件的源代码。
  • 参阅 https://www.gnu.org/philosophy/free-sw.html 了解自由软件的定义。
  • 根据开源协议的定义,开源软件在技术上与自由软件在授权方面类似。
  • 开源软件的定义参见 https://www.opensource.org/docs/osd

讲解

这段文字是自由软件基金会(FSF)对"自由软件"的定义。"自由"不是价格免费,而是言论自由的自由。

  • 自由度0:你可以把软件用在任何地方,包括商业产品,没人能限制使用目的。
  • 自由度1:你有权获得源码并修改它。这是开源的价值------你能修复bug、增加功能。
  • 自由度2:你可以把原始软件拷贝给别人。
  • 自由度3:你可以把你修改过的版本也分发给别人。

注意:自由度1和3的前提是"必须能访问到源代码"。所以自由软件许可证都要求提供源码。

"开源软件"与"自由软件":在授权方面基本相同,只是哲学出发点不同。自由软件强调道德伦理,开源软件强调开发方法论。大部分情况下你可以混用两个词。

初学者理解:这些自由不是无条件的------某些许可证(比如GPL)要求你修改后的代码也必须公开。这就是下一个要讲的Copyleft。


(五)Copyleft 与 非 Copyleft 许可证

  • 自由软件许可证分为两大类
    • Copyleft 许可证
    • 非 Copyleft 许可证
  • Copyleft 的概念是在给予用户的自由中要求互惠。
  • 结果是,当您在 Copyleft 自由软件许可证下收到软件并分发它的修改版本时,您必须在相同的许可证下进行
    • 新用户享有同样的自由
    • 回馈您的更改而不是将它们保密是一种激励
  • 非 copyleft 许可证没有这样的要求,修改后的版本可以成为专有的,但它们仍然需要署名

讲解

Copyleft("著佐权") :你可以自由使用、修改、分发,但有一个条件:如果你分发了修改后的版本,必须也在相同的许可证下公开你的源码。这是为了防止有人把开源代码改一下变成闭源产品。

  • 典型代表:GPL(GNU General Public License)。
  • 效果:如果你在商业产品中使用了GPL代码,你的整个产品可能被迫开源(取决于如何使用,后面会说)。

非Copyleft(宽松许可证):允许你把修改后的代码变成专有的(闭源),不需要公开你的修改。唯一要求通常是保留版权声明(署名)。

  • 典型代表:MIT、BSD、Apache 2.0。
  • 效果:你可以放心地使用这些库,即使你的产品闭源也没问题。这是商业公司最喜欢的许可证。

初学者概念:你在选择开源组件时,第一件事就是看许可证。如果组件是GPL,你需要请律师评估风险;如果是MIT/BSD,基本安全。


(六)GNU通用公共许可证(GPL)详解

  • GNU通用公共许可证
  • 涵盖约55%的免费软件项目
    • 包括Linux内核、BusyBox和许多应用程序
  • 是copyleft许可证
    • 要求衍生作品在同一许可下发布
    • 与在GPL下发布的库链接的程序也必须在GPL下发布
  • 版本2涵盖的一些程序(Linux内核、BusyBox、U-Boot...)
  • 2007年发布的第3版涵盖了许多程序:gcc、bash、grub、samba、Qt...
    • 嵌入式市场的重大变化:如果设备是消费类设备,则要求用户必须能够在设备上运行修改后的版本
  • 不分发软件时无义务使用GPL
    • 您可以对您的修改保密,直到产品交付
  • 如果满足以下条件之一,则它被授权分发二进制版本:
    • 在物理介质上传送带有源副本的二进制文件
    • 使用有效期为3年的书面报价传送二进制文件,说明如何获取源代码
    • 使用可以找到源代码的位置的网络地址传送二进制文件
    • 参见GPL许可证的第6节
  • 在所有情况下,必须保留署名和许可

讲解

GPL是最常见也是"最严格"的自由软件许可证。你需要特别注意。

关键条款

  • 如果你修改了GPL代码并分发(比如修改了Linux内核),那么你必须公开你的修改。
  • 如果你的应用程序链接了GPL库(静态或动态),那么你的应用程序也必须遵循GPL(即开源)------这就是所谓的"传染性"。

GPL v2 vs v3

  • v2相对宽松一点,没有强制要求"用户能在设备上运行修改后的版本"。
  • v3增加了反Tivoization条款:如果设备是消费类产品(如机顶盒、路由器),你必须允许用户安装他们自己编译的修改版软件。这对某些嵌入式厂商造成困扰(他们不希望用户刷第三方固件)。

如果你不分发(比如只内部使用):你修改GPL代码完全不需要公开。只有当你把二进制发给客户(分发)时,才有义务提供源码。

如何合规分发(三种方式):

  1. 随二进制一起提供源码光盘或U盘。
  2. 随二进制提供一份书面报价(有效期3年),客户付钱后可获得源码。
  3. 在二进制旁边提供一个网络地址,写明从哪里下载源码(最常见)。

初学者提醒:千万不要在闭源产品中直接静态链接或使用GPL库(比如BusyBox、Linux内核的一部分驱动模块也是有风险的)。如果不确定,问法务。


(七)常见的非Copyleft许可证

  • 许多非 Copyleft 许可证,它们的许可相对类似
  • 举例
    • Apache license(约 4%)
    • BSD license(大约 6%)
    • MIT license(大约 4%)
    • X11 license
    • Artistic 许可(约 9%)

讲解

这些许可证通常称为"宽松许可证"。不同许可证之间细微差别,但共通点:不强制公开修改后的源码

  • MIT 许可证:最简短、最宽松。只需要保留版权声明和许可声明。几乎所有公司都能接受。
  • BSD 许可证:类似MIT,但有条款禁止使用作者名义进行广告宣传(旧BSD)或无条件(新BSD)。
  • Apache 2.0 许可证:比MIT/BSD多一条"专利授权",如果你使用了Apache项目,项目贡献者授予你专利使用权。同时也禁止使用项目商标。常见于Google的项目。
  • X11许可证:类似MIT。
  • Artistic 许可证:Perl语言使用,也比较宽松。

使用场景:如果你的产品是闭源的,应该优先选择MIT、BSD、Apache 2.0许可证的组件。例如:libcurl(MIT)、SQLite(Public Domain,类似)、OpenSSL(Apache/BSD-like)等。

初学者注意 :即使这些许可证不要求开源,你必须 在产品的相关文档或关于页面中注明使用了这些组件,并附上许可证原文(通常放在 LICENSES/ 目录或文档中)。不署名也违规。


(八)实际应用中的许可证遵守要点+风险

  • 大多数自由软件项目都覆盖了大约 10 个知名的许可证,因此大多数项目都会对许可证有一个很好的说明。
  • 查看自由软件基金会的意见和开源计划的意见。
  • 否则,请阅读许可文本说明

示例:

  • 您分发包含 GPL 或 LGPL 软件的系统 → 必须准备好提供相应源代码。
  • 您对 Linux 内核、BusyBox、U-Boot 或其他 GPL 软件进行修改 → 必须在同一许可下发布修改版本。
  • 您对 C 库或任何其他 LGPL 库进行修改 → 必须在相同的许可下发布修改版本。
  • 您创建了一个依赖 LGPL 库的应用程序 → 可以保持专有,但必须与 LGPL 库进行动态链接
  • 您对非 Copyleft 许可软件进行修改 → 可以保留修改,但必须感谢作者(署名)。

讲解

给出了更具体的合规做法:

情况1 :你的整个系统镜像包含GPL软件(比如Linux内核、BusyBox、U-Boot)。只要你分发这个镜像,就要给客户提供这些GPL软件的完整源代码(包括你可能修改过的部分)。这可以放在公司网站下载。

情况2:你修改了Linux内核、U-Boot或BusyBox。你必须发布你修改后的源码(即使你不想公开)。很多人以为"我只在内部用就不用",但一旦卖出设备就算分发。

情况3 :你修改了LGPL库(比如glibc)。LGPL是"较宽松GPL",它允许动态链接而不传染你的应用程序,但对库本身的修改仍需公开。

情况4:你开发了一个应用程序,动态链接了LGPL库(比如glibc、Qt的LGPL版本)。你的应用程序可以保持闭源,不需要公开。

情况5:你修改了一个MIT/BSD的软件,可以闭源,只要保留原作者的版权声明。

初学者理解:LGPL对商业公司更友好。如果你必须使用Linux内核(GPL),那是避不开的,但一般你只需要公开内核源码就够了,应用层可以闭源。


(九)许可证合规风险和组织帮助

  • 自由软件不是公共领域的软件,分发者有义务根据许可行使相应权利
    • 在使用免费软件组件之前,请确保许可证符合您的项目限制。
    • 确保保留您使用的免费软件包的完整列表、您使用的原始版本号,并将您的修改和改编与原始版本分开。
    • Buildroot 和 Yocto Project 可以为你生成这个列表!
    • 产品交付给客户之前,请遵守许可要求。
  • 自由软件许可证已在法庭上已成功判决
  • 风险:
    • 用户向版权所有者投诉,版权所有者可以起诉您。
    • 竞争对手可能会在您的固件(存在二进制扫描工具)中寻找侵犯版权的行为,以试图让您的产品从市场上撤出,直到问题得到解决。
  • 可以帮助解决问题的组织:
    • 软件自由法律中心
    • 软件自由保护协会
  • 咨询您的法律部门!

讲解

这部分很重要:违反开源许可证不是"小事",已经有法院判例。

主要风险

  • 个人或组织(比如软件自由保护协会)专门扫描市面上的设备固件,检查是否违反GPL。他们可以代表版权所有者起诉。
  • 竞争对手也可能利用你的违规行为,向市场监督部门举报,让你的产品强制下架,直到整改完成。

如何避免

  • 在产品开发初期就列出所有使用的开源组件及其许可证。
  • 将你的修改单独放在补丁文件或独立目录中,与原始源码清晰分离。
  • 使用Buildroot或Yocto生成许可清单(它们会自动帮你收集每个包的许可证信息,并生成license.manifest文件)。
  • 发货前,确保源码准备好可下载。

如果你不是律师:遇到复杂情况,让公司法务介入。你的职责是提供组件列表和修改情况。

初学者建议:个人学习阶段不用太紧张,但进入公司开发,一定要遵守合规流程。


(十)SSH服务器和客户端:Dropbear

ssh server and client: Dropbear

  • 用于嵌入式系统的非常小的内存占用 ssh 服务器
  • 满足大多数需求。客户端和服务器!
  • 大小:204 KB,在 ARM 上用 musl 动态编译
  • 用于:
    • 在目标设备上获取远程控制台
    • 将文件复制到目标设备(scp 或 rsync)或从目标设备复制文件。
  • OpenSSH 的替代方案,用于桌面和服务器系统。

讲解

当你的开发板运行Linux后,你想通过网络远程登录它(而不是总用串口),就需要SSH服务器。

OpenSSH 功能全面,但它体积大(几MB),依赖多,不适合资源受限的嵌入式设备。

Dropbear 是专门为嵌入式设计的轻量级SSH实现:

  • 整个二进制只有200KB左右。
  • 同时支持SSH客户端和服务器。
  • 支持scp文件传输(基于SFTP或SCP)。

使用场景

  • 产品量产后,维护人员通过网络ssh进入设备调试。
  • 开发阶段,你可以在Wi-Fi网络下 ssh root@开发板IP 登录,比插串口线方便。
  • 使用 scp myapp root@开发板IP:/tmp 快速部署新程序。

初学者 :Buildroot里选中 dropbear 包,编译进根文件系统。启动后默认一般没有密码或root密码为空(注意安全)。这是每个嵌入式工程师的必备工具。


(十一)为什么许多网络设备使用Web界面

  • 许多支持网络的设备只能有一个网络接口
    • 示例:调制解调器/路由器、IP 摄像机、打印机等。
    • 无需为连接到设备的计算机开发驱动程序或应用程序。无需支持多种操作系统!
    • 只需要开发静态或动态 HTML 页面(可能使用强大的客户端 JavaScript)。提供对设备信息和参数访问的简单方法。
    • 降低硬件成本(无 LCD,且需要很少的存储空间)。

讲解

你家里的路由器是不是没有屏幕,但你可以用电脑浏览器输入 192.168.1.1 来配置它?这就是嵌入式设备使用Web界面的典型案例。

为什么不用专门的PC客户端软件?

  • PC客户端需要为Windows、macOS、Linux各开发一个版本,还要随时更新维护。
  • 用户还要安装软件,麻烦。
  • Web界面跨平台,只要设备支持HTTP服务,任何有浏览器的设备都能访问。

好处

  • 不需要硬件LCD屏幕,省成本。
  • 存储空间小(Web页面是HTML/CSS/JS,服务器是lighttpd或BusyBox httpd,加起来几百KB)。
  • 可以远程访问(如果设备有公网IP或内网穿透)。

初学者:以后你做一个网关、智能摄像头、智能音箱,很可能也要实现一个Web后台。所以了解嵌入式Web服务器很有用。


(十二)嵌入式Web服务器:BusyBox httpd 及其他

  • BusyBox http 服务器:https://busybox.net
    • 小巧:只为 BusyBox 增加 20 K(在手臂上动态链接,启用所有功能。)
    • 具有 Web 界面的许多设备的足够功能,包括 CGI、http 身份验证、脚本支持(如 PHP,具有单独的解释器)、反向代理...
    • 许可证:GPL
  • 其它开源实现:轻量级服务器,如 Boa、httppd、lightppd、nginx 等
  • 一些产品使用的是 Node.js,它足够轻量级。low.js 更轻巧,可在 Linux 和微控制器上使用。

讲解

在嵌入式设备中运行一个Web服务器,最轻量级的选择是 BusyBox 自带的httpd

  • 它集成在BusyBox内,如果你已经用了BusyBox,开启httpd功能只增加20KB。
  • 支持基本的GET、POST、CGI(Common Gateway Interface)------你可以编写Shell脚本或C程序动态生成页面。
  • 支持HTTP基本认证、虚拟主机、反向代理简单功能。

其他选择(功能更强但体积稍大):

  • lighttpd:比较受欢迎,安全、快速、支持FastCGI、WebSocket,内存占用1-2MB左右。
  • nginx:功能强大,配置复杂,体积略大于lighttpd,但也很流行。
  • Boa / httppd:更简单的,但很久未更新。

Node.js 和 low.js:如果你喜欢用JavaScript写后端,可以在嵌入式设备上跑Node.js(需要更多内存,至少32MB RAM)。low.js是专门为低资源设备优化的Node.js替代。

初学者建议:先用BusyBox httpd跑一个简单的CGI脚本(比如在网页上显示板子IP和温度),体验完整流程。需要更复杂功能再换lighttpd。


(十三)网络相关工具(Avahi、bind、iptables等)

  • avahi 是多播 DNS 服务发现的实现,它允许程序在本地网络上发布和发现服务
  • bind,一个DNS服务器
  • iptables,与 Linux 防火墙 Netfilter 相关的用户空间工具
  • iw and wireless tools,与无线设备相关的用户空间工具
  • netsnmp,SNMP 协议的实现(设备监控)
  • chrony,网络时间协议的实现,用于时钟同步
  • openssl,一个用于 SSL 和 TLS 连接的工具包
  • pppd,点对点协议的实现,用于拨号连接
  • samba,实现了 SMB 和 CIFS 协议,Windows 使用它来共享文件和打印机
  • coherence, UPnP/DLNA 实现
  • vsftpd、proftpd、FTP 服务器

讲解

列出了嵌入式Linux中常用的网络相关开源组件(注意,图片内容在你有两组重复,这里按第一次出现的讲解):

1. avahi :实现 mDNS/DNS-SD (苹果Bonjour)。当你的设备插上网线,其他电脑可以在浏览器里直接输入 mydevice.local 访问它,不需要手动配IP。智能家居产品常用。

2. bind :完整DNS服务器。一般用在比较大的路由器或网络设备,小设备用 dnsmasq 更常见(更轻量)。

3. iptables:Linux内核防火墙的用户空间配置工具。几乎每个路由器都有。通过iptables可以实现端口转发、IP过滤、NAT等。

4. iw / wireless tools:无线网卡的配置工具,扫描Wi-Fi、连接AP、设置发射功率等。

5. netsnmp:简单网络管理协议。网络管理员可以通过SNMP监控你的设备状态(CPU、内存、网络流量)。企业级产品常常要求支持。

6. chrony:网络时间协议(NTP)客户端/服务器。让设备自动同步时间。比老牌ntpd更适合间歇断网的嵌入式环境。

7. openssl:加密库。任何需要HTTPS、SSH、加密通信的软件底层都依赖它。注意openssl许可证曾有问题,现在Apache 2.0。

8. pppd:点对点协议。用于旧的拨号上网、3G/4G模块(PPP拨号)。

9. samba:实现Windows文件共享协议。如果设备需要作为NAS或向Windows机器共享文件夹,就用它。

10. coherence / UPnP:通用即插即用。设备可以在局域网自动被发现,比如媒体服务器。

11. vsftpd / proftpd:FTP服务器。传输文件用,但如今更多用SSH/SFTP代替。

初学者:先了解iptables和openssl,几乎每个产品都会用到。其他看项目需求。


(十四)系统实用程序(dbus、gpsd、libusb等)

  • dbus,一种应用程序面向对象的通信总线。
  • gpsd,一个解析和共享 GPS 数据的守护进程
  • libusb,一个无需编写内核驱动程序即可访问 USB 设备的用户空间库。
  • 内核子系统的实用程序:用于 I2C 的 i2c-tools、用于输入的 input-tools、用于 MTD 设备的 mtd-utils、用于 USB 设备的 usbutils。

讲解

这些是系统级别的工具,让应用程序与硬件或系统服务通信更方便。

  • dbus:桌面Linux广泛使用,嵌入式也越来越常见。它允许进程间通信(IPC),例如:你的应用程序可以发送dbus消息请求网络管理器连接Wi-Fi。很多现代嵌入式系统(如使用systemd或bluez蓝牙栈)依赖dbus。
  • gpsd:如果设备有GPS模块,gpsd负责读取串口或USB的GPS数据,解析出经纬度、时间、速度,并通过socket共享给多个应用程序。不会出现两个程序同时抢串口的情况。
  • libusb:允许用户空间程序直接控制USB设备,不需要写内核驱动。适合快速原型。
  • 内核工具包
    • i2c-tools:读写I2C总线上的设备寄存器,调试传感器等非常有用。
    • input-tools:测试键盘、触摸屏等输入设备。
    • mtd-utils:操作NAND Flash、NOR Flash分区(擦除、写入、读取坏块表)。
    • usbutilslsusb命令,查看USB设备信息。

初学者 :这些工具在调试硬件时很有用。例如连上一个I2C温度传感器,可以用 i2cdetect 查看设备地址,用 i2cget 读寄存器。


(十五)脚本语言解释器

  • 提供最常见脚本语言的解释器,常用于:
    • 应用开发
    • 网络服务开发
    • 脚本
  • 支持的编程语言
    • shell(bash、sh...)
    • Lua,简单的嵌入式C应用。
    • python
    • Perl
    • Ruby
    • TCL
    • PHP

讲解

嵌入式设备上除了C/C++,经常还需要脚本语言来快速实现功能。

  • Shell (bash, sh):启动脚本、初始化系统、定时任务,几乎每个嵌入式Linux都有BusyBox的ash。
  • Lua:非常轻量(内核<200KB),执行效率高,常嵌入C程序做配置或逻辑。比如很多网络设备用Lua写Web界面(如OpenWrt的uci)。
  • Python:功能强大,但体积大(完整版几十MB)。适合内存充足(>64MB)的设备。MicroPython是极精简版,但只适合单片机。
  • Perl / Ruby / TCL:现在较少用于新嵌入式项目,体积较大。
  • PHP:用于Web开发,一些旧设备用PHP写网页后台(不如直接写CGI脚本或Node.js)。

初学者:学习Shell脚本是必备技能。Lua值得了解一下(很多物联网产品用)。Python如果资源够用,可以快速开发应用。


(十六)多媒体框架和编解码库(GStreamer等)

  • GStreamer,一个多媒体框架
    • 允许对各种编解码器进行解码/编码(FFmpeg)。
    • 通过插件支持硬件编解码器和解码器,专有/特定插件通常由 SoC 供应商提供。
  • alsa-lib,与 ALSA 内核声音子系统关联的用户空间库
  • 直接使用编解码库:libavcodec、libvpx、libflac、libopus、libmad 等

讲解

如果你的嵌入式产品需要播放视频、录音、网络摄像头,就会用到这些多媒体组件。

GStreamer :是一个管道式多媒体框架。你创建一条处理链:"源 → 解码器 → 转换 → 显示"。例如:filesrc location=video.mp4 ! decodebin ! autovideosink。优点是可以利用硬件解码(SoC厂商提供插件),CPU占用很低。

ALSA :Linux音频子系统。alsa-lib 提供 aplayarecord 命令和编程接口。嵌入式如果要播放或录制声音,需要它。

直接使用编解码库:如果你不想用重量级的GStreamer,可以直接调用:

  • libavcodec(ffmpeg):支持几乎所有格式。
  • libvpx:VP8/VP9编码。
  • libmad:MP3解码。
  • libopus:高质量有损音频(VoIP常用)。

初学者 :如果只是简单的音频播放,用 aplay 就够了。需要做视频处理,学习GStreamer基本概念。注意硬件编解码需要SoC厂商提供专有插件,比如NXP i.MX6ULL有VPU单元。


(十七)图形套件:GTK

Gtk

  • 著名的工具包,提供基于widget的高级API来开发图形应用程序
  • C语言中的标准API,但存在针对各种语言的绑定:C++、Python等。
  • X.org和Wayland之上工作。
  • 没有窗口系统,运行多个应用程序需要一个轻量级的窗口管理器。可能的解决方案:Matchbox。
  • License: LGPL
  • 多平台:Linux、MacOS、Windows。
  • 官网 https://www.gtk.org

讲解

如果嵌入式设备需要图形界面(比如医疗仪器、工控HMI),可以选择GTK或Qt。

GTK(GIMP Toolkit):

  • 用C语言开发,API面向对象风格。
  • 许可证LGPL,对商业应用友好(动态链接即可闭源)。
  • 依赖X11或Wayland显示服务器。单独运行GTK程序需要一个窗口管理器,最小方案是Matchbox(专门为嵌入式设计的轻量级窗口管理器)。
  • 官方支持Linux、Windows、macOS,跨平台。

嵌入式适用性:GTK比Qt资源占用稍小,但文档和社区活跃度不如Qt。很多嵌入式图形选择Qt。

初学者:如果你喜欢C语言,可以尝试GTK写个简单的Hello World界面。Buildroot里有gtk3包,选中即可。


(十八)X.Org Foundation(Kdrive架构)

应用程序通过toolkit与X.org KDrive服务器通信,KDrive通过fbdev驱动和内核硬件。

讲解

X.Org是Linux桌面上传统的显示服务器。在嵌入式领域,它的一个轻量级变种叫 Kdrive(也称Xfbdev)。

  • Kdrive直接操作Linux的framebuffer设备(/dev/fb0),不需要完整的X服务器。
  • 它体积小,适合没有GPU的设备。
  • 应用程序(GTK、Qt等)通过Xlib或更高层toolkit与Kdrive通信。

现状:现在新的嵌入式图形项目更倾向于使用Wayland(下一张图),但X11/Kdrive仍在很多老产品中服役。

初学者:了解即可,知道嵌入式可以用X做图形,但更推荐Wayland。


(十九)Wayland显示服务器

Wayland

  • 更简单的 X 替代品
  • Wayland 是一种供合成器与其客户对话的协议,以及该协议的 C 库实现。
  • Weston: Wayland 合成器的最小且快速的参考实现,适用于许多嵌入式和移动用例。
  • 大多数图形工具包(Gtk、Qt、EFL...)现在都支持 Wayland。
  • 大多数桌面发行版都支持它:Fedora、Debian、Ubuntu(从 21.04 开始)

架构图:Wayland Client ↔ Wayland Compositor(通过Wayland协议) → Kernel(KMS/evdev)

讲解

Wayland是X11的现代替代品,设计更简单、更安全、更适合嵌入式。

  • X11使用C/S架构,通过网络透明但复杂;Wayland直接把客户端和合成器(显示管理器)通信,减少拷贝,效率高。
  • 在嵌入式领域,你可以运行一个Weston合成器(参考实现),然后在其上运行Qt/GTK应用程序,不需要X11。
  • Weston支持多种后端:framebuffer、DRM/KMS、RDP、VNC等,非常灵活。

为什么嵌入式用Wayland更好

  • 资源占用小。
  • 没有X服务器那么多历史包袱。
  • 支持现代图形特性(如直接渲染、防撕裂)。

初学者:如果你的项目需要图形界面,优先考虑Wayland + Qt/GTK,而不是X11。Buildroot中也支持Weston。


(二十)Qt图形框架

Qt

  • 一个著名的工具包,提供基于小部件的高级 API 来开发图形应用程序
  • C++语言实现
    • Target系统需要 C++ 库
    • C++使用的标准 API,但有其他语言的绑定
  • 可以工作在 Framebuffer / X11 / wayland
  • 支持多平台:Linux、MacOS、Windows。
  • 拥有非常丰富的文档教程
  • 官网:https://www.qt.io/
  • License: LGPLv3 和 GPLv3 混合,使得非 GPL 应用程序难以实现。根据客户的说法,商业许可非常昂贵。

讲解

Qt是嵌入式图形界面开发的首选框架,尤其适合需要复杂交互和动画的产品(汽车仪表、医疗设备、智能家居中控)。

特点

  • 使用C++,但提供Python绑定(PyQt/PySide)。
  • 可以不用任何显示服务器,直接操作Linux Framebuffer(称为Qt for Embedded Linux或Qt EGLFS)。
  • 也可以在X11或Wayland上运行。
  • 提供的模块:核心、网络、多媒体、QML(声明式界面)、WebEngine(Chromium内核)、蓝牙、串口等等。

许可证问题

  • Qt有LGPLv3版本,理论上你可以动态链接并闭源。
  • 但LGPLv3有一些限制,且很多附加模块(如Qt Charts、Qt Virtual Keyboard)是GPL或商业许可。
  • 很多公司选择购买Qt商业许可(昂贵),避免法律风险。

初学者:如果你想在开发板上做一个漂亮的界面,先尝试Qt。利用Buildroot,选中qt5或qt6包,编译出带Qt的系统,然后写一个简单的QML程序跑起来。


(二十一)WebKit网络浏览器引擎

https://webkit.org/

  • 网络浏览器引擎。可用于开发 Web 浏览器或向应用程序添加 HTML 渲染功能的应用程序框架。您还可以用全屏浏览器(更容易实现)替换您的应用程序。
  • License: LGPL 中的部分和 BSD 中的其他部分允许专有应用。
  • 被许多网络浏览器使用:Safari、iPhone 和 Android 默认浏览器......谷歌浏览器现在使用其 WebCore 组件的一个分支)。电子邮件客户端也使用它来呈现 HTML。
  • 多个图形后端:Qt、GTK、EFL...

讲解

WebKit 是最流行的开源浏览器引擎。在嵌入式设备中,你可以用它来:

  • 做一个完整的Web浏览器(比如智能电视的浏览器)。
  • 在你的应用程序中嵌入一个Web视图(显示帮助文档、登录页面等)。
  • 用HTML/CSS/JS写整个用户界面,然后用全屏的WebKit浏览器作为"容器",这样开发速度极快(类似Electron,但更轻量)。

许可证友好:大部分核心是LGPL或BSD,允许闭源应用使用。

嵌入式注意事项 :WebKit 体积大(几十MB),内存占用高(启动后上百MB),只有内存充足(>256MB)的设备才适合。低端设备上替代方案是 WebView 使用更精简的 libwpecog

初学者:如果你内存大,可以尝试;否则先了解即可。


面试官提问环节(必考!)

以下问题是在你学完这文档后,面试官/领导很可能问到的核心问题。每个问题配有详细答题思路,建议你先自己回答一遍,再看参考答案。


第1问:你在产品中使用了Linux内核和BusyBox,它们是什么许可证?你要遵守哪些义务?

面试官:你们公司准备推出一款智能路由器,基于Linux和BusyBox,还修改了内核的一些驱动。请问,你们在法律上有哪些必须做的事?为什么?

你的回答

Linux内核和BusyBox都是 GPLv2 许可证,属于严格的 copyleft 许可证。因为我们把这些软件(包括修改后的版本)打包到路由器中并卖给客户,属于"分发",因此必须遵守以下义务:

  1. 提供完整的对应源代码 :我们不仅要提供内核和BusyBox的原始源码,还要提供我们所做的修改(比如驱动改动)。通常的做法是:在公司官网开设一个下载页面,写明"本产品使用的开源软件源码下载",并附上源码压缩包或提供git仓库链接。这个源码必须在分发二进制的同时或随后的三年内持续可获取。
  2. 保留版权声明和许可证声明:在产品的文档、关于页面或源码包中,必须保留所有原始版权信息和GPL许可证文本,不能删除。
  3. 不能对用户追加额外限制:不能通过技术手段阻止用户修改并重新运行修改后的软件(GPLv2对此要求相对宽松,但GPLv3有"反Tivoization"条款,内核是v2,所以不强制,但最好遵循精神)。

如果不遵守,我们可能被起诉,产品被下架,公司声誉受损。所以我们要在发货前准备好所有GPL源码包。


第2问:GPL和LGPL有什么区别?我在开发一个闭源应用程序,想使用某个库,应该优先选哪个许可证?

面试官:你的应用程序需要用到图片解码库。有两个候选:libpng(许可证类似MIT)、libjpeg-turbo(BSD-3-Clause),以及一个GPL库。你会怎么选?为什么?

你的回答

GPL :如果我的应用程序链接 了GPL库(无论是静态还是动态链接),那么我的整个应用程序也被视为"衍生作品",必须按照GPL开源。这不符合公司闭源的要求,所以绝对不能在闭源产品中使用GPL库。

LGPL:允许动态链接(共享库方式),而不传染应用程序。我的应用程序可以保持闭源,只要用户能够自己替换库的版本(即动态链接)。如果我修改了LGPL库本身,则修改后的库必须开源,但应用仍可闭源。

非Copyleft许可证(MIT、BSD、Apache) :没有任何传染性,我可以静态或动态链接,修改库本身也不需要公开(但必须保留版权声明)。这是闭源商业产品的首选

所以对于图片解码,我会选libpng或libjpeg-turbo(均为宽松许可证)。GPL库直接排除。如果只有LGPL库可用,我会确保动态链接,并遵守LGPL的条款。


第3问:嵌入式设备上想通过浏览器配置设备,用什么Web服务器最轻量?怎么做到动态内容?

面试官:你设计的产品只有8MB Flash、32MB RAM,需要提供Web配置界面。你会选择哪种Web服务器?如何让网页显示设备当前IP地址?

你的回答

最轻量的选择是 BusyBox 自带的httpd。它集成在BusyBox中,启用后只增加约20KB代码,非常节省空间。

要实现动态内容(如显示当前IP),可以使用 CGI (Common Gateway Interface)

  1. 编写一个Shell脚本或C程序,放在 /www/cgi-bin/ 目录下,比如 get_ip.cgi
  2. 脚本内容:#!/bin/sh 然后 ifconfig eth0 | grep 'inet addr' | cut -d: -f2 | cut -d' ' -f1 输出IP。
  3. 在HTML页面中,用 <img src="/cgi-bin/get_ip.cgi"> 或者用Ajax请求 /cgi-bin/get_ip.cgi 来获取IP并显示。
  4. 配置BusyBox httpd启用CGI支持:httpd -c /etc/httpd.conf -h /www,并在配置文件中允许CGI目录。

如果内存稍大(64MB+),也可以考虑lighttpd,它内置FastCGI,性能更好。但最轻量首选BusyBox httpd。


第4问:嵌入式设备上想增加一个图形界面,你会选Qt还是GTK?为什么?

面试官:你的产品需要一个触摸屏界面,显示图表和按钮,性能要求不高但需要稳定。公司大部分程序员熟悉C++。你会选择Qt还是GTK?许可证方面需要注意什么?

你的回答

我会选择 Qt。理由如下:

  • 语言匹配:公司熟悉C++,Qt就是C++原生框架,上手快。
  • 功能丰富:Qt有QML、绘图、网络、多媒体模块,做图表和动画很省力。
  • 嵌入式支持:Qt可以直接跑在Linux Framebuffer上(不需要X11或Wayland),节省资源。
  • 社区和文档:Qt文档非常完善,商业支持也好。

许可证方面

  • Qt提供LGPLv3版本,我可以动态链接Qt库,这样我的应用程序可以保持闭源。但需要注意LGPLv3的一些附加条款,且部分Qt模块(如Qt Charts)是GPL,不能随意使用,要么买商业许可,要么替换。
  • 如果公司预算足,购买Qt商业许可可以完全规避开源风险。

GTK也不错,但使用C语言,开发效率稍低,且生态不如Qt丰富。对于嵌入式触摸屏产品,Qt是更主流的选择。


第5问:为什么现在很多嵌入式产品从X11转向Wayland?Wayland有什么优势?

面试官:你看到一些嵌入式Linux的图形系统在用Wayland而不是传统的X11。请说几个Wayland的主要优势。

你的回答

Wayland相比X11有以下嵌入式优势:

  1. 更简单,资源占用低:X11设计于1980年代,协议庞大,服务器复杂,内存占用几十MB。Wayland协议只有几千行代码,Weston合成器轻量。
  2. 渲染效率高:在X11中,客户端渲染画面要传给X服务器,再合成显示,至少两次拷贝。Wayland客户端直接渲染到共享内存或GPU表面,合成器只做叠加,无需额外拷贝,适合视频播放、游戏。
  3. 安全:X11允许任何客户端监听其他客户端的输入事件(键盘记录)。Wayland严格隔离,窗口只能看到自己的内容。
  4. 更适合嵌入式:Weston可以直接操作DRM/KMS显示驱动,不需要单独运行X服务器,启动更快,无闪烁。

当然,X11成熟,有些老旧应用依赖X,但新开发推荐Wayland。


第6问:在你的嵌入式系统中,你希望设备能被局域网内其他设备用 mydevice.local 访问,无需配置IP。你需要添加什么软件?

面试官 :你开发了一个智能摄像头,它通过DHCP获得动态IP。用户不想每次查IP再输浏览器。你有什么办法让用户直接用 camera.local 访问?

你的回答

需要使用 mDNS(多播DNS)DNS-SD(服务发现) 。在嵌入式Linux中,通常用 Avahi 软件包实现。

具体做法:

  1. 在Buildroot中选中 avahi 包(以及 avahi-daemonavahi-autoipd 可选)。
  2. 配置Avahi,为设备定义一个主机名,比如 camera
  3. 启动avahi-daemon后,它会通过组播地址 224.0.0.251 发送DNS记录,宣告 camera.local 解析到自己的IP。
  4. 用户电脑(支持Bonjour或Avahi客户端)在浏览器输入 http://camera.local 就能访问。

另外,如果还需要让用户发现HTTP服务类型,可以在Avahi中注册 _http._tcp 服务,这样支持DNS-SD的浏览器会直接列出摄像头。


结束语

以上文档和6个面试问题涵盖了嵌入式Linux中开源组件复用、许可证合规、常用网络/多媒体/图形工具的核心知识。作为初学者,你不需要记住每个组件的细节,但必须理解:

  • 为什么要复用开源组件(节约成本)
  • 许可证分类(GPL vs LGPL vs BSD/MIT)
  • 常用轻量级组件(Dropbear、BusyBox httpd、Avahi、Qt/Wayland)

这些知识点在实际产品开发中几乎天天用到,也是面试必考点。祝你学有所成,再也不怕领导考核!

相关推荐
计算机安禾2 小时前
【Linux从入门到精通】第34篇:搭建FTP与Samba——跨平台文件共享解决方案
linux·运维·服务器
日取其半万世不竭2 小时前
用 Netdata 实时监控服务器,比 Prometheus + Grafana 轻量得多
linux·服务器·网络·系统架构·负载均衡·zabbix·grafana
jamon_tan2 小时前
Linux下cmake构建方法
linux
JiaWen技术圈2 小时前
内核子系统 nf_tables 深度解析
linux·服务器·安全·运维开发
计算机安禾2 小时前
【Linux从入门到精通】第32篇:Nginx入门——高性能Web服务器搭建
linux·服务器·nginx
ZenosDoron2 小时前
Linux 中,rm -r 和 -f
linux·运维·服务器
Hello.Reader2 小时前
Ubuntu 上正确安装 Kali 虚拟机、Docker 与 kail 工具指南
linux·ubuntu·docker
原来是猿2 小时前
Linux UDP Socket 编程入门:Echo Server/Client实现
linux·运维·udp
中微子3 小时前
突然爆火的Warp 终端,开源1天破 4w Stars
linux·人工智能·开源