前言
OpenWRT 是一款家用路由器的操作系统,可以被描述为一个嵌入式的 Linux 发行版,路由器安装了它才能正常的工作。就像国内手机厂商基于开源的 Android 系统开发出各种 Rom一样。路由器厂商也可以基于 OpenWRT 这个平台,进行二次开发,增加更多丰富的功能和有厂商特色的路由器系统。独立开发者们同样也可以基于 OpenWRT 开发各种各样的插件,使搭载了 OpenWRT 的路由器具备更丰富的功能。
作为使用者我们可以选择网上丰富的开源镜像直接烧录,但是我们也可以做一高度定制化的固件,今天就来分享一下openwrt编译开发过程,帮助大家进行openwrt的使用。本文是我openwrt开发使用的开篇,后续会有更多文章分享。
作者:良知犹存
转载授权以及围观:欢迎关注微信公众号:羽林君
或者添加作者个人微信:become_me
openwrt介绍
什么是 OpenWrt:
OpenWrt(官网 www.openwrt.org)可以被描述为一个嵌入式的 Linux 发行版,目前常用在路由器上,但是作为基于 linux 系统的它,其实可以做更多的事情。
它是一个高度模块化、高度自动化的嵌入式 Linux 系统,拥有强大的网络组件和扩展性,还可被用于工控设备、电话、小型机器人、远程监控、智能家居以及 VOIP 设备中。
它不同于其他许多用于路由器的发行版(主流路由器固件有 dd-wrt,tomato,OpenWrt 三类),它是一个从零开始编写的、功能齐全的、容易修改的路由器操作系统。实际上,这意味着我们能够使用单独想要的功能而不加进其他的累赘,而支持这些功能工作的 linux kernel又远比绝大多数发行版来得新(linux 内核中很多源代码都是由 OpenWrt 社区提供的)。
openwrt下载编译烧录
文件介绍
下载openwrt的源码,地址如下:https://github.com/openwrt/openwrt.git
git clone https://github.com/openwrt/openwrt.git cd openwrt/
下载之后进入openwrt目录,可以看到有如下子文件下载之后进入openwrt目录,可以看到有如下子文件
scripts
存放了一些脚本,使用了 bash,Python,perl 等多种脚本语言.编译过程中,用于第三方软件包管理的 feeds 文件也是在这个目录当中.在编译过程中,使用到的脚本也统一放在这个目录中
tools
编译时,主机需要使用一些工具软件,tools 里包含了获取和编译这些工具的命令.软件包里面有 Makefile 文件,有的还包含了 patch.每个 Makefile 当中都有一句$(eval $(callHostBuild)),这表明编译这个工具是为了在主机上使用的.
config
存放着整个系统的配置文件
docs
包含了整个宿主机的文件源码的介绍, 里面还有 Makefile 为目标系统生成 docs.使用make -C docs/可以为目标系统生成文档.
toolchain
做过嵌入式的童鞋应该都知道交叉编译链,这个文件中存放的就是编译交叉编译链的软件包.包括:binutils,gcc,libc 等等.
target
openwrt 的源码可以编译出各个平台适用的二进制文件,各平台在这个目录里定义了firmware 和 kernel 的编译过程。
package
存放了 openwrt 系统中适用的软件包,包含针对各个软件包的 Makefile。openwrt 定义了一套 Makefile 模板.各软件参照这个模板定义了自己的信息,如软件包的版本、下载地址、编译方式、安装地址等。在二次开发过程中,这个文件夹我们会经常打交道。事实上,通过./scripts/feed update -a 和./scripts/feed install -a 的软件包也会存放在这个目录之中。
include
openwrt 的很多 Makefile 都存放在这里。文件名为 *.mk 。这里的文件上是在Makefile 里被 include 的,类似于库文件.这些文件定义了编译过程
feeds
openwrt 的附加软件包管理器的扩展包索引目录.有点绕,简单来说就是下载管理软件包的.默认的 feeds 下载有 packages、management、luci、routing、telephony。如要下载其他的软件包,需打开源码根目录下面的 feeds.conf.default 文件,去掉相应软件包前面的#号,然后更新源:
./scripts/feeds update -a 安装下载好的包: ./scripts/feeds install -a
build_dir
在前面的原始目录中,我们提到了 host 工具,toolchain 工具还有目标文件.openwrt
将在这个目录中展开各个软件包,进行编译.所以这个文件夹中包含 3 个子文件夹:
host
在该文件夹中编译主机使用的工具软件
toolchain-XXX
在该文件夹中编译交叉工具链
target-XXX
在此编译目标平台的目标文件,包括各个软件包和内核文件.openwrt 系统的 linux 解压后的源码在
bin
保存编译完成后的二进制文件,包括:完整的 bin 文件,所有的 ipk 文件.
dl
在编译过程中使用的很多软件,刚开始下载源码并没有包含,而是在编译过程中从其他服务器下载的,这里是统一的保存目录
staging_dir
用于保存在 build_dir 目录中编译完成的软件.所以这里也和 build_dir 有同样的子目录结构. 比如,在 target-XXX 文件夹中保存了目标平台编译好的头文件,库文件.在我们开发自己的 ipk 文件时,编译过程中,预处理头文件,链接动态库,静态库都是到这个子文件夹中.
tmp
从名字来看,是临时文件夹.在编译过程中,有大量中间临时文件需要保存,都是在这里.
更新
./scripts/feeds update -a
./scripts/feeds install -a
安装时候可能会提示如下错误:
出现awk: include/scan.awk: line 21: function asort never defined
这个是缺少插件问题,解决这个问题,直接apt安装工具,如下:
sudo apt-get install subversion build-essential libncurses5-dev zlib1g-dev gawk git ccache
再次
./scripts/feeds install -a,这次就不会出现问题
menuconfig
紧接着make menuconfig进入配置
首先就是需要进行芯片和机器型号选择,大部分人是知道我们购买路由器型号,但是机器芯片型号是不知道的,这个可以网络查询一下,我是通过ssh登录机器进行cat /proc/cpuinfo查看的芯片型号,最后一招大家也可以拆机查看芯片型号。
这是我自己的机器芯片型号:
第一界面选择好对应的芯片型号
Target Profile设置设备型号
Target Images —>
[*] squashfs —> 设置好编译输出的镜像类型,默认也是squashfs,可以不用管
开始编译
首推make V=s
进行编译源码,V=s 是用来生成编译信息的,方便用户查找出错原因。不建议加“-j x”(x 为数字)选项,那样可能会导致有时很难查找错误原因。
如果直接make如下所示,这个时候编译过程都被省略了
而使用V=s编译过程中会有每个文件编译信息
编译过程的分析
这个是在查看编译时候,我们可以看到,openwrt会下载一堆文件,文件解压之后发现会进行apply打补丁操作,然后进行编译,这个操作做模块话编译很方便,像之前Linux其他设备编译时候,我们会看到各种芯片定义文件都有,然后编译的时候进行选择编译,而openwrt直接进行了精简,源码是最精简的,每次选择之后网络下载包,进行打补丁之后编译,这个操作对很大项目或者项目维护的方案很执行推荐。
Patch补丁打入:
打完补丁之后的文件编译
执行细节confdata.c文件记录
执行细节conf.c文件记录
编译完成
我们可以在package下面的openwrt下的ipk安装包
bin/target对应的芯片名称下面看到编译好的镜像文件
这几个bin文件的介绍:原文链接:https://blog.csdn.net/GK_Ph/article/details/85775737
在下载openwrt系统时,经常能看到initramfs-kernel.bin,squashfs-factory.bin,squashfs-sysupgrade.bin等结尾的文件,factory适用于从原厂系统刷到openwrt,sysupgrade则是从openwrt刷到openwrt(已经是openwrt系统,在openwrt系统中更新自己),squashfs则是一种文件系统,适用于嵌入式设备。那么initramfs-kernel又是什么呢。
initramfs是放在内存RAM中的rootfs 映像文件,跟kernel放在一起。一般来说用不到initramfs-kernel.bin来刷机,因为启动后,所有的配置在路由器重启后都不能保留(毕竟ram文件系统,所有文件放在ram中,断电就没了)。但也有用到initramfs-kernel.bin的时候,就是在移植openwrt系统的时候,没有设备上的flash闪存的驱动的时候。
此外对于sysupgrade和uimage对比具体的内容大家也可以参考此文:https://www.cnblogs.com/sherlock-merlin/articles/9323572.html
拷贝到机器中进行烧录
scp openwrt-ramips-mt7621-xiaomi_redmi-router-ac2100-squashfs-kernel1.bin root@ 192.168.1.1:/tmp/
登录机器查看
进行烧写
在非openwrt机器上使用mtd write /tmp/openwrt-ramips-mt7621-xiaomi_redmi-router-ac2100-squashfs-kernel1.bin kernel1
最后面kernel1是mtd的分区,mtd具体的分区大家可以通过命令查看。
cat /proc/mtd
在已经是openwrt机器上,我们可以使用sysupgrade工具:
sysupgrade -F openwrt-ramips-mt7621-xiaomi_redmi-router-ac2100-squashfs-kernel1.bin
-F是强制覆盖
烧录完之后重启,再进行连接,查看自己的修改,进行验证自己是否烧录正常
sysupgrade命令的详细使用,大家可以参考此文:https://www.cnblogs.com/sammei/p/3973322.html
此外openwrt有luci界面也可以进行烧录
mtd和 systemupgrad都可以
结语
这就是我自己分享的openwrt编译使用。如果大家有更好的想法和需求,也欢迎大家加我好友交流分享哈。