自编译树莓派 OpenWrt 完全指南 (一) : 环境搭建

文章更新

20190323 初次成文

写在前面

很久之前就打算写一篇有关 OpenWrt 编译的教程,结果因为自己的原因,这篇教程从 2018 年拖(咕)到了 2019 年 3 月 (也就是说这算一篇跨年教程了?),趁着论文前的这段空档时间,再不抓紧时间把之前挖过的坑填上的话以后就有可能咕更久了,于是就有了这篇教程~

在之前的文章中小苏有提到过 “我的编译教程要比别人的更简单”,为了“让编译更简单”,在这篇教程中小苏将会使用打包好的 Docker 镜像作为 OpenWrt 的编译环境,并且会将编译过程中需要下载的众多源码和依赖包单独提供出来,尽量减少大家编译时漂洋过海下载源码包的麻烦。

特别说明:本文中提供的 dl.tar.gz (下文中会提及) 不保证 100% 适用于除树莓派外的其他情况和设备,除此之外的内容应该适用于其他大部分设备。

前期准备

在这篇教程中,为了成功搭建 OpenWrt 编译环境,你需要准备:
系统为 Linux 或 macOS 的 PC 或 Server 设备(需要支持安装 Docker);
科学上网环境(最好部署到路由器上)。
挂载目录所在分区剩余空间应大于 50G 。

搭建环境

在接下来的操作中,假定你已经安装并配置好 Linux 系统、 Docker 环境,Docker 环境的一系列安装和配置步骤(包括但不限于配置 Docker 加速器,加入 sudo 用户组)可以从 Docker - 从入门到实践 项目中找到~

配置好 Docker 环境及加速器后,在终端中执行:

docker --version

若可以正确返回类似如下的 Docker 的版本信息即为安装成功~

Docker version 18.06.3-ce, build d7080c1

安装和配置好 Docker 环境之后,我们需要拉取编译所需的 Docker 镜像。这里的 Docker 镜像是小苏通过 Dockerfile 构建的,镜像中包含 OpenWrt 编译所需的所有依赖环境和一些常用工具,除此之外镜像中还配置好了 zsh,oh-my-zsh,以及一系列 zsh 插件 (git / sudo / zsh-syntax-highlighting / zsh-autosuggestions),可以说是开箱即用的一个 Docker 镜像。

因为镜像基于 Ubuntu 14.04 构建,所以小苏在 “前期准备”一节中并没有规定需要安装某种指定的 Linux 发行版,所以不论你的机器上安装了哪种 Linux 发行版,在 OpenWrt 编译的整个过程始终在容器内的 Ubuntu 14.04 中进行,这样的好处是可以保持编译环境的高度一致性,基本上杜绝了因编译环境不同导致的编译失败的情况,同时也可以省去大家对编译环境的配置,有助于提高效率和编译成功率~

关于此镜像的更多信息:
Dockerfile :
https://github.com/SuLingGG/openwrtenv
Docker Hub:
https://hub.docker.com/r/sulinggg/openwrtenv

好了,不自卖自夸了,我们需要执行以下命令拉取编译所需的 Docker 镜像:

docker pull sulinggg/openwrtenv

镜像拉取过程中为分层拉取,拉取完成后可以看到类似如下信息:

Using default tag: latest
latest: Pulling from sulinggg/openwrtenv
e082d4499130: Pull complete 
371450624c9e: Pull complete 
c8a555b3a57c: Pull complete 
1456d810d42e: Pull complete 
4ce8c7c9791d: Pull complete 
cfbcf6e48aaf: Pull complete 
Digest: sha256:13c93c3895421d8f70f3c39f9403c6c7299601b190351aedf81e9190e059f73c
Status: Downloaded newer image for sulinggg/openwrtenv:latest

接下来我们需要在主机上新建一个目录作为编译过程中的挂载目录:

mkdir ~/workspace

接下来我们使用刚刚拉取的镜像建立一个名为 openwrtenv 的容器:

docker run -itd -v ~/workspace:/home/admin/workspace --name openwrtenv sulinggg/openwrtenv

其中:
-v ~/workspace:/home/admin/workspace 表示将刚刚建立的文件夹 ~/workspace 挂载到容器中的 /home/admin/workspace 文件夹中(若容器中此文件夹不存在则会递归新建);
--name openwrtenv 表示新建的容器名为 openwrtenv;
sulinggg/openwrtenv表示将使用 sulinggg/openwrtenv 镜像创建容器。

命令执行完毕后,返回结果中如果只返回容器的 sha256 值则说明容器创建成功。

接下来我们执行以下命令进入容器:

docker exec -it openwrtenv zsh

其中:
openwrtenv为容器名称;
zsh为此次执行的容器中的命令,一般情况下选用 bashsh,但因为小苏在镜像中已经配置好了 zsh,所以可以直接选用 zsh

执行后我们将会看到类似的提示:

# root @ 6883dad1f91e in / [18:58:25] 
$ 

此时当前用户为默认的 root 用户,而 OpenWrt 不能使用 root 用户编译,针对这种情况,小苏在镜像中建立并配置了普通用户 admin,接下来我们需要把刚刚挂载到容器的 workspace 文件夹的所有者改为 admin 以使 admin 用户可以正常读写此目录 (感谢评论区 :) 的指出):

chown -R admin:admin /home/admin/workspace

完成 workspace 文件夹的所有者更改后,我们执行命令切换用户为 admin:

su admin

此时我们便切换到了普通用户 admin:

# admin @ 6883dad1f91e in / [18:58:50] 
$ 

接下来我们切换目录为普通用户 admin 的 home 目录,看看下面有什么东西:

cd ~ && ls

我们可以看到 admin 用户的 home 目录下 (/home/admin) 存在一个 workspace 文件夹,这个文件夹就是我们挂载到容器中的挂载文件夹,即主机下的 ~/workspace 文件夹,主机中的这个文件夹中的内容将与容器中的 /home/admin/workspace 文件夹保持同步,即容器中文件夹中的内容改变情况会同步到主机,主机中的内容改变情况也会同步到容器。
之后的编译工作就在 workspace 文件夹中进行。

编译准备

环境已经搭建完毕,接下来进入编译前的准备阶段。(从现在开始应该保持全程科学上网状态)

首先我们切换到容器内的 workspace 文件夹并且把 Lean 大的 OpenWrt 仓库克隆到本地:

cd ~/workspace && git clone https://github.com/coolsnowwolf/lede

除了编译所需的环境镜像之外,小苏还为大家提供了编译过程中需要的一些依赖和源码包,并将它们打包成了一个文件,将文件解包到指定目录后,在编译过程中就不需要漂洋过海去下载了:

注:此文件 (dl.tar.gz) 不保证 100% 适用于除树莓派外的其他情况和设备

cd ~/workspace/lede && wget http://netdisk.club/DockerRes/BuildRes/dl.tar.gz

如果上面的链接下载速度慢的话,也可以试试这个,但下载文件时必须处于科学上网环境下,否则此文件无法下载成功:

cd ~/workspace/lede && wget https://image.moeclub.org/GoogleDrive/1DnECAO7PDL_lR-9kneyLshM7unwr_6Ma -O dl.tar.gz

下载完成后解压:

tar -zxvf dl.tar.gz

接下来安装和更新必要的软件包:

./scripts/feeds update -a
./scripts/feeds install -a

测试编译环境:

make defconfig

配置固件菜单:

make menuconfig

在“配置固件菜单”这一步内中,我们需要选择编译对象设备的 CPU 平台、CPU 型号、固件格式、固件分区大小、包含的软件包以及其它选项。

开始编译:

make V=99 -j1

编译所用时间与设备硬件性能,添加的软件包多少,CPU 线程数有关。

编译完成后的固件、ipk 软件包及其他资料将存放到 OpwnWrt 项目仓库的 bin 文件下,如果你严格按照本文教程操作,编译完成后的一系列文件将存放在容器的 /home/admin/workspace/lede/bin 文件夹下,同时因为我们使用了挂载目录的原因,这些文件也会永久存放在到主机的 ~/workspace/lede/bin 文件下。

至此,OpenWrt 编译教程的第一部分就结束了,在下一篇 “完全指南” 中,小苏将重点讲讲 make menuconfigmake V=99 -j1 这两项,同时,这两项也是编译过程中的重头戏。
另外,除本文提到的 dl.tar.gz 文件外,此教程的大部分内容应该适用于绝大多数情况和设备。

更多编译细节,请看下一篇~

参考资料

OpenWrt By Lean · coolsnowwolf/lede - GitHub:
  https://github.com/coolsnowwolf/lede

OpenWrt Project Document - The build system:
  https://openwrt.org/docs/guide-developer/build-system/start

OpenWrt Environment · SuLingGG/openwrt - GitHub:
  https://github.com/SuLingGG/openwrtenv

SuLingGG/openwrtenv - Docker Hub:
  https://hub.docker.com/r/sulinggg/openwrtenv

Docker 从入门到实践 · yeasy/docker_practice - GitHub:
  https://github.com/yeasy/docker_practice

从零开始编译OpenWRT/LEDE固件 - GXNAS博客:
  https://wp.gxnas.com/2367.html

已有 16 条评论
  1. :)

      老哥,跟着走一波,发现在git clone那步提示权限问题。然后看了下,容器里面workspace文件夹权限是:
    $ ll /home/admin
    total 0
    drwxr-xr-x. 2 root root 6 Mar 30 02:04 workspace
    这样切去admin用户没有写权限,得先手动chmod 777 /home/admin/workspace才行。

    1. 感谢反馈~确实是有这个问题,之前确实也遇到了,但因为这篇文章是根据之前的笔记写的,当时遇到这个问题的时候没有把之前的笔记更新,写文章的时候也没有想起来这茬,所以这次就留下这个问题啦...我的锅我的锅~

  2. 钟文博

    我有一个安装了最新树莓派官方系统的树莓派3b+,我是不是要重烧系统,还是说在上面安装docker然后继续就行了

    1. 你是想编译 OpenWrt 吗?
      编译 OpenWrt 需要在电脑上操作的...

      1. 钟文博

        我想把我的树莓派3b+变成一个路由器。。。虽然大佬的教程已经写的很简单了,但是我还是不知道第一步应该干什么。。买个可以的无线网卡还是。。。不太懂。。。

        1. 可以看一下这篇文章:
          https://mlapp.cn/369.html
          这篇文章里面有我编译好的 OpenWrt 固件,下载解压之后把固件像刷入官方系统一样刷入 SD 卡就可以把树莓派变成路由器了。

          1. 钟文博

            那就剩一个问题了,我校的有线校园网。。需要客户端登录http://ncc.hust.edu.cn/xzzx1/rzkhd.htm
            大佬有空能帮我看看,用树莓派3b+做的路由器能连上网吗

            1. Google 了一下你们学校可能是使用锐捷认证的。我的固件里面没有带有锐捷认证的组件,不过锐捷认证组件在 OpenWrt 上应该已经挺成熟的了,你可以 Google 关键词 "华中科技大学 OpenWrt" 或者 "OpenWrt 锐捷" 应该可以找到一些有用的信息。但是可能需要自己编译 MentoHUST 。资金充裕的话你也可以直接购买支持此固件的路由器,然后刷入此固件,里面自带锐捷拨号插件。

  3. :)

      拉取最新镜像启动容器,root用户没法修改归属。换俩虚拟机都这样,chmod改权限也不行。
      # root @ 1b3aa26fbc77 in / [9:04:22]
      $ chown -R admin:admin /home/admin/workspace
      chown: cannot read directory '/home/admin/workspace': Permission denied

    1. 我这儿没有这个问题...
      你可以 cd /home/admin
      然后 chown -R admin:admin workspace 试试看...

  4. :)

      嗯......还是不行,root用户chown和chmod都是提示Permission denied。

    1. :)

        找到原因,用的CentOS 7,后面更新内核SELinux状态好像默认变成Enforce,导致Docker容器内的Root用户权限不足无法操作挂载目录,容器run的时候再加上参数--privileged=true即可。

      1. 跑 Docker 我还是建议宿主机用 Debian 系,没有那么多问题.../笑哭

        1. :)

            问题不大,不慌。

  5. Hemin Ye

    不知道为什么我编译你上面的源码不成功!
    checking whether mknod can create fifo without root privileges... configure: error: in `/home/admin/workspace/lede/build_dir/host/tar-1.30':
    configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
    See `config.log' for more details
    make[3]: *** [/home/admin/workspace/lede/build_dir/host/tar-1.30/.configured] Error 1
    make[3]: Leaving directory `/home/admin/workspace/lede/tools/tar'
    time: tools/tar/compile#8.53#3.28#18.43
    make[2]: *** [tools/tar/compile] Error 2
    make[2]: Leaving directory `/home/admin/workspace/lede'
    make[1]: *** [/home/admin/workspace/lede/staging_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/stamp/.tools_compile_yynyyyyynyyyyynyynnnyyyynyyyyyyyyyyyyyyynnyynynnyyynnyy] Error 2
    make[1]: Leaving directory `/home/admin/workspace/lede'
    make: *** [world] Error 2

    这是错误信息,而且每次编译都得用sudo才能编,否则就提示禁止!

  6. 作者有空编译一下这款单片机的吗,属于一款类树莓派
    tinkerboard
    https://www.asus.com/us/Single-Board-Computer/Tinker-Board/
    https://github.com/TinkerBoard/debian_kernel.git
    https://github.com/TinkerBoard/debian_u-boot.git

添加新评论