菜鸟视角的openwrt(二) 完成一个编译openwrt固件的小目标

   上一篇,我们认识了bootloader和openwrt, 了解了他们之间的关系。

   为了来点成就感,我们来编译一个openwrt固件, 当看到自己编译的openwrt固件跑起来的时候,你会感叹“原来如此”,相信你对openwrt的兴趣将会有增无减。
   
   为了测试你的固件, 你首先得有一块板子吧, 或者一个支持openwrt的路由器吧, 我用的YDH-MT76X8kit 评估板, 天猫买的,不到100(这里有广告嫌疑, 其实我只是一买家,但为了写清楚编译过程, 还是明确一下的好)。
   为了尽快获得成就感,买块板子是值得的,特别是为了工作。因为商家一般提供有与板子配套的sdk, 这样编译成功的可能性几乎100%,不至于打击入门者脆弱的心灵。
   
    当然你也可以不要实物, 就是为了体验一把编译的过程, 如果编译成功,也能获得一定程度上的成就感。
   
   需要提一下的是:
       openwrt的编译环境是linux环境, 所以你至少需要了解几个linux的命令吧!
         如果你想在openwrt下面做应用开发,了解几个linux命令是必须的吧!
       ubuntu是网站上搜索openwrt编译环境时用到的最多的环境了,主要是ubuntu安装应用软件太方便了。

         商家文档中使用的就是ubuntu系统,
         我因为电脑上是现成的CentOS6.8_X86, 不想换系统, 所以就抱着试试看的态度在上面搭建环境, 结果居然成功了。

   说明一下:
       1)商家提供的文档中提供了配套SDK开发包的下载地址:  https://github.com/ivotten/YDH.git
       2)编译过程中要用到的需要在编译时下载的各种程序包,商家已经帮我们下载好了,联系商家可以获得这个包
       3)由于网络限制原因, 你在编译过程中下载这些包, 一方面影响编译速度, 一方面由于部分网被“墙”,一些包可能下载失败, 编译成功的机会不大。对老鸟来说, 可能会使用各种办法解决掉问题; 而我等菜鸟一旦编译失败,一条编译错误就可能让你放弃学习,可能需要很久才能获得重启的动力。这会极大打击我们学习openwrt的信心,这也是我们建议买个由技术支持的商家的开发板的缘由。以我为例,再次学习openwrt,距离我上次开学, 期间间隔了两年了吧!

     
       4)从YDH的源码地址获得源码并进入源码的ubuntu分支的命令有3条:
      cd  dir_sdk_study                               dir_sdk_study 是我们为了编译openwrt而创建的工作目录
    git clone https://github.com/ivotten/YDH.git    这个命令将下载整个源码仓库,到dir_sdk_study, 这个时间比较长, 耐心等待就可以了
      git check ubuntu                        这个命令将从源码仓库中获得ubuntu分支的源码,用于在linux系统下编译openwrt固件
                                                                        注意ubuntu分支只是商家给linux系统编译的openwrt源码分支起的一个名字, 并非只能在ubuntu下用, 我就是在CentOS下编译这个分支源码的

       5)商家提供了64位Win7下的ubuntu系统的虚拟机文件, 很大。 不过每跑起来,商家说我的电脑配置低了,跑不起, 所以我才决定在我的64位CentOS6.8上先试试, 不行再安ubuntu系统,结果成功了, 所以不用换系统了。后面我同事在i5 CPU的上跑虚拟机成功了, 据他说bios里面还有个啥设置,我忘了。


      好了现在介绍下我编译的过程:

      一)  安装源码下载以及编译环境

        //下载CentOS的国内软件仓库文件, 这样使用国内的镜像网站,安装软件会快点
    wget http://mirrors.163.com/.help/CentOS6-Base-163.repo                
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
    mv CentOS6-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo

    //更新软件仓库内的软件包信息
    yum clean all                                              //            
    yum makecache
    yum update

    //安装软件包, 作为菜鸟,我晓得git是下载源码用的,其实我也不晓得到底需要那些包, 反正从网上搜了一下, 在CentOS下就用这个好了
      //CentOS安装时, 我选的“软件开发工作站”选项, 应该好多与开发有关的软件包都安装好了, 比如下面软件包gcc 和gcc-c++, 不过我按原操作来记录,就不改动了
    yum install binutils bzip2 gawk gcc gcc-c++ gettext makencurses-devel patch unzip wget zlib-devel git subversion screen


      二)  升级gcc编译器
          什么要升级?
          CentOS6.8自己带的gcc编译其版本很低, 是4.4版本吧, 貌似连C++11的编准都不支持。
             我最开始没升级编译器, 后面发现编译不过, 升级到4.8, 还是不行, 查了下ubunbu的编译器, 已经是5点几了。 好吧, 就升级到5点几吧。

        //下面的语句为CentOS增加gcc编译器的软件仓库源,然后在安装gcc 5.2并把系统默认编译器改为新安装的编译器     
       wget https://copr.fedoraproject.org/coprs/hhorak/devtoolset-4-rebuild-bootstrap/repo/epel-6/hhorak-devtoolset-4-rebuild-bootstrap-epel-6.repo -O /etc/yum.repos.d/devtools-4.repo
       yum install devtoolset-4-gcc devtoolset-4-binutils devtoolset-4-gcc-c++ -y
       source /opt/rh/devtoolset-4/enable

         
      三) 下载源码仓库并进入源码的ubuntu分支, 这个前面已经讲过了, 此处在重复下, 菜鸟嘛!
      cd  dir_sdk_study                               dir_sdk_study 是我们为了编译openwrt而创建的工作目录
    git clone https://github.com/ivotten/YDH.git    这个命令将下载整个源码仓库,到dir_sdk_study, 这个时间比较长, 耐心等待就可以了
      git check ubuntu                        这个命令将从源码仓库中获得ubuntu分支的源码,用于在linux系统下编译openwrt固件


      四) openwrt源码包信息更新, 目的是从openwrt官方下载最新的openwrt软件包更新信息(比如增加了xx软件包)供配置openwrt组件时进行选择, 大概是这意思吧, 反正照着做就是了
    ./scripts/feeds update -a        这个需要一点点时间, 抽只烟吧!
    ./scripts/feeds install -a
          
      五) 配置openwrt需要编译的组件,照着厂家提供的开发文档来做就行了,
         对于菜鸟来说,肯定有点摸不着头脑, 不过记住, 我们现在的目标是: 编译一个openwrt固件, 其他的先不关心。
         不过为了说明下make menuconfig的作用, 还是举个例子:
              比如, 我想编译出来的openwrt能够支持U盘, 那么我需要在配置内核时选中USB驱动,以及一些配套的驱动, 如果你不选, 编出来的东东就不认识你的U盘         
                      如果我不想编出来的东东支持声音播放, 我在配置时, 就不要选中对声卡的支持。

         对于我这块板子,执行make menuconfig 就开始进入openwrt的固件配置了, 因为图形化的配置界面,make menuconfig会先编译一个小程序出来实现最终的配置。

         为了实现“ 编译一个openwrt固件”的小目标, 我仅作了如下配置
        1) 在弹出的make menuconfig主菜单的第1项: 选择目标系统类型,也就是MCU芯片的体系
            Ralink RT288x/RT3xxx
        2) 在弹出的make menuconfig主菜单的第2项: 选择开发板的类型
            MT7628 based boards
        3) 在弹出的make menuconfig主菜单的第3项: 选择包含了一些默认配置项的profile文件,profile文件为我们提供一些默认的配置选择
            YDH iot Board

        作为一个菜鸟, 其实永远也搞不懂到底是配置了啥, 何必伤脑筋呢?
        反正就是: 适用于这款芯片, 适用于这块板子,  带有某些基本功能(如网络支持)

        等你弄明白了, 你又进入到另外一个层次了, 不需要看这种层次的文章了。
        其实本来好多板子就是芯片厂商提供的原型板, 或者有些下改动。
        使用 openwrt的最初来源也是那些openwrt狂热分子提供的最初版本, 你我菜鸟级别, 何必纠结呢?
        饭要一口一口吃,路要一步一步走。


         插曲: 前面讲到,在make menuconfig , make menuconfig会先编译一个小程序来执行图形化配置功能, 会出现一个编译错误:
        lxdialog/checklist.o: undefined reference to symbol 'acs_map'
                提示acs_map函数不能存在, 网上搜了下,acs_map函数在库文件libtinfo中有。 至于ubuntu下为啥没这个提示, 我也不知道。
                熟悉c语言的朋友知道,这是因为ld连接命令中,缺少相应的库链接, 因为对菜鸟来说makefile实在是天书,  到底连接参数在哪里添加呢?
                错误提示的上一行:
                Entering directory `/home/MT7628/YDH/scripts/config'
                好嘛, 我就去/home/MT7628/YDH/scripts/config目录下去找Makefile文件碰下运气。
                搜索 ld, 找到这么一行:
                 $(CC) -o $@ $^ $(call check_lxdialog,ldflags $(CC))
            ldflags应该就是连接参数了, ldflags在哪里定义的呢? 半天每找到, 算了,直接加在尾巴上就是了
                 $(CC) -o $@ $^ $(call check_lxdialog,ldflags $(CC))  -ltinfo
                再次执行: make menuconfig
                配置菜单顺利出现了。

             **后来我再看了下makefile文件, 发现这么一行:
        check_lxdialog = $(shell $(SHELL) $(CURDIR)/lxdialog/check-lxdialog.sh -$(1))
             难道实在文件check-lxdialog.sh里?
             打开文件,ldflags()貌似一个函数, 看不懂, 也许ubuntu和CentOS下, 这个ldflags()执行结果有点不一样吧!

            *** 再后来, 我执行make_kernel_menuconfig命令, 又是同样的问题:
        scripts/kconfig/lxdialog/checklist.o: undefined reference to symbol 'acs_map'
            解决办法一样,观察到
        Entering directory `/home/MT7628/YDH/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.18.29'
            打开该目录下,scripts/kconfig/lxdialog/Makefile, 搜索ld, 找到一行:
        $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
        还是添加 -ltinfo
            $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) -ltinfo
            再次:
        make_kernel_menuconfig  就可以了。
        

    六) 编译
             执行编译前, 先把商家提供的dl.tar.gz压缩包解压缩到工作目录的dl目录下, 这样编译时就不必到网上去下载软件包源码了,大大加快了编译速度
          命令 make V=99

       在编译过程中, 在编译cmake-2.8.12.2时, 又出现了提示某函数不能存在,原因还是找不要 libtinfo库文件
              这时, 需要在编译目录build_dir, 找到下面的文件:
        build_dir/host/cmake-2.8.12.2/Source/CMakeFiles/ccmake.dir/link.txt
            在文件的最后一行添加连接参数:  -ltinfo

            重新   make V=99 就可以了


       七) 编译结果查看:
            在工作目录下的bin子目录下
            bin/ramips/openwrt-ramips-mt7628-ydh-squashfs-sysupgrade.bin就是我们的目标了
            
           如果你没有开发板, 你也完成了一个编译“openwrt”固件的小目标了。


       八)升级开发板上的固件
             这块开发板使用的是一个叫做breed的bootloader的, 功能强大, 可以通过浏览器来升级固件。
             当然你需要用网线把PC机和板子连接好,并且设置同一网段的IP地址
             输入: http:/xxx.xxx.xxx.xxx
             根据web页面的提示, 升级openwrt固件
             升级完后,重启开发板, 开发板的初始IP为192.168.1.1
             板子启动后, 执行ping 192.168.1.1
             如果成功, 证明你的固件已经正常运行啦!  
             现在你是不是觉得, 编译一个openwrt固件就这么容易, 你需要的就是一点点等待时间。
             如果你再次去逛恩山论坛, 面对各种固件的介绍, 是不是觉得没有原来那么神秘了呢?

            提醒:
             openwrt官方网站提供了很多现成的模块, 可以通过openwrt的 opkg 包管理命令来安装
                  我偶然下载了一个USB摄像头头驱动,发现不能用, 后来自己在编译配置中加入USB摄像头支持, 能正常使用。
                  我估计是编译器版本不同吧, 反正自己能编固件了,一切都好办!




    


         






 

   

 
 

      
             


 

猜你喜欢

转载自blog.csdn.net/twd_1991/article/details/80227083
今日推荐