最近想研究一下Openwrt,因而開始搭建openwrt環境,雖然如今沒有現成的板子,可是html
能夠先編譯起來。linux
openwrt的特色是基於下載 -> patch -> 編譯 的一個工做模式,openwrt整個包一開始下載下來也不是很大,由於裏面git
基本上沒有源碼,要在編譯的時候下載。github
看了別人的帖子,都推薦使用svn從官網下載源碼,json
svn co svn://svn.openwrt.org/openwrt/trunk/
可是實際測試發現它的速度太慢了,爲了獲得官方的源碼,從github上找到了它:ubuntu
https://github.com/openwrt-mirror/openwrt
將它下載下來以後,要安裝一些必要的包來編譯它,我使用的是ubuntu12.04.網絡
sudo apt-get install flex g++ gawk zlib1g-dev libncurses5-dev libssl-dev subversion
先看一下它的目錄樹:架構
tree -d -L 2 . ├── config ├── docs ├── include │ └── site ├── package │ ├── base-files │ ├── boot │ ├── devel │ ├── firmware │ ├── kernel │ ├── libs │ ├── network │ ├── system │ └── utils ├── scripts │ ├── config │ └── flashing ├── target │ ├── imagebuilder │ ├── linux │ ├── sdk │ └── toolchain ├── toolchain │ ├── binutils │ ├── gcc │ ├── gdb │ ├── glibc │ ├── insight │ ├── kernel-headers │ ├── musl │ ├── uClibc │ └── wrapper └── tools ├── autoconf ├── automake ├── b43-tools ├── bc ├── bison ├── ccache ├── cloog ├── cmake ├── dosfstools ├── e2fsprogs ├── elftosb ├── findutils ├── firmware-utils ├── flex ├── flock ├── genext2fs ├── gengetopt ├── gmp ├── include ├── libelf ├── libtool ├── lzma ├── lzma-old ├── m4 ├── missing-macros ├── mkimage ├── mklibs ├── mm-macros ├── mpc ├── mpfr ├── mtd-utils ├── mtools ├── padjffs2 ├── patch ├── patchelf ├── patch-image ├── pkg-config ├── ppl ├── qemu ├── quilt ├── scons ├── sed ├── sparse ├── squashfs ├── squashfs4 ├── sstrip ├── upslug2 ├── upx ├── wrt350nv2-builder ├── xz └── yaffs2
首先是更新一下feed:app
./scripts/feeds update -a
./scripts/feeds install -a
這裏的-a表示更新全部的feed,那麼這裏有哪些feed呢,能夠從log裏面看出來:less
tan@love:~/openwrt-git/openwrt$ scripts/feeds update -a Updating feed 'packages' from 'https://github.com/openwrt/packages.git' ... Cloning into './feeds/packages'... remote: Counting objects: 3682, done. remote: Compressing objects: 100% (2941/2941), done. remote: Total 3682 (delta 488), reused 3055 (delta 247), pack-reused 0 Receiving objects: 100% (3682/3682), 2.00 MiB | 24 KiB/s, done. Resolving deltas: 100% (488/488), done. Create index file './feeds/packages.index' Collecting package info: done Collecting target info: done Updating feed 'luci' from 'https://github.com/openwrt/luci.git' ... Cloning into './feeds/luci'... remote: Counting objects: 11683, done. remote: Compressing objects: 100% (6278/6278), done. remote: Total 11683 (delta 3832), reused 9770 (delta 2394), pack-reused 0 Receiving objects: 100% (11683/11683), 8.42 MiB | 85 KiB/s, done. Resolving deltas: 100% (3832/3832), done. Create index file './feeds/luci.index' Collecting package info: done Collecting target info: done Updating feed 'routing' from 'https://github.com/openwrt-routing/packages.git' ... Cloning into './feeds/routing'... remote: Counting objects: 441, done. remote: Compressing objects: 100% (343/343), done. Receiving objects: 100% (441/441), 242.46 KiB | 58 KiB/s, done. remote: Total 441 (delta 81), reused 330 (delta 38), pack-reused 0 Resolving deltas: 100% (81/81), done. Create index file './feeds/routing.index' Collecting package info: done Collecting target info: done Updating feed 'telephony' from 'https://github.com/openwrt/telephony.git' ... Cloning into './feeds/telephony'... remote: Counting objects: 268, done. remote: Compressing objects: 100% (222/222), done. remote: Total 268 (delta 51), reused 211 (delta 22), pack-reused 0 Receiving objects: 100% (268/268), 140.49 KiB | 102 KiB/s, done. Resolving deltas: 100% (51/51), done. Create index file './feeds/telephony.index' Collecting package info: done Collecting target info: done Updating feed 'management' from 'https://github.com/openwrt-management/packages.git' ... Cloning into './feeds/management'... remote: Counting objects: 40, done. remote: Compressing objects: 100% (28/28), done. remote: Total 40 (delta 7), reused 27 (delta 2), pack-reused 0 Unpacking objects: 100% (40/40), done. Create index file './feeds/management.index' Collecting package info: done Collecting target info: done Updating feed 'targets' from 'https://github.com/openwrt/targets.git' ... Cloning into './feeds/targets'... remote: Counting objects: 137, done. remote: Compressing objects: 100% (95/95), done. remote: Total 137 (delta 17), reused 122 (delta 16), pack-reused 0 Receiving objects: 100% (137/137), 130.80 KiB | 44 KiB/s, done. Resolving deltas: 100% (17/17), done. Create index file './feeds/targets.index' Collecting package info: done Collecting target info: done
能夠從上面的網址看出來更新的feed。
更新feed後目錄樹的變化:
. ├── config ├── docs ├── feeds │ ├── luci │ ├── luci.tmp │ ├── management │ ├── management.tmp │ ├── packages │ ├── packages.tmp │ ├── routing │ ├── routing.tmp │ ├── targets │ ├── targets.tmp │ ├── telephony │ └── telephony.tmp ├── include │ └── site ├── package │ ├── base-files │ ├── boot │ ├── devel │ ├── feeds │ ├── firmware │ ├── kernel │ ├── libs │ ├── network │ ├── system │ └── utils ├── scripts │ ├── config │ └── flashing ├── staging_dir │ └── host ├── target │ ├── imagebuilder │ ├── linux │ ├── sdk │ └── toolchain ├── tmp │ └── info ├── toolchain │ ├── binutils │ ├── gcc │ ├── gdb │ ├── glibc │ ├── insight │ ├── kernel-headers │ ├── musl │ ├── uClibc │ └── wrapper └── tools ├── autoconf ├── automake ├── b43-tools ├── bc ├── bison ├── ccache ├── cloog ├── cmake ├── dosfstools ├── e2fsprogs ├── elftosb ├── findutils ├── firmware-utils ├── flex ├── flock ├── genext2fs ├── gengetopt ├── gmp ├── include ├── libelf ├── libtool ├── lzma ├── lzma-old ├── m4 ├── missing-macros ├── mkimage ├── mklibs ├── mm-macros ├── mpc ├── mpfr ├── mtd-utils ├── mtools ├── padjffs2 ├── patch ├── patchelf ├── patch-image ├── pkg-config ├── ppl ├── qemu ├── quilt ├── scons ├── sed ├── sparse ├── squashfs ├── squashfs4 ├── sstrip ├── upslug2 ├── upx ├── wrt350nv2-builder ├── xz └── yaffs2
而後使用:
make menuconfig
make
編譯的過程會持續好幾個小時,由於編譯的時候還須要在線下載工具包,若是網絡慢的話就會
更慢了。
關於make的做用,README是這樣說的:
Simply running "make" will build your firmware. It will download all sources, build the cross-compile toolchain, the kernel and all choosen applications.
中文手冊是這樣說的:
OpenWrt選擇了另外一種方式來生成固件:下載,打補丁,編譯,一切從零開始,即便交叉編譯鏈也是如此。
一開始下載openwrt源碼的時候,也就大約300MB,可是裏面基本上沒有代碼,大部分
都是配置文件。
openwrt的英文文檔以下:
https://downloads.openwrt.org/kamikaze/docs/openwrt.html
在編譯過程當中,使用make -j V=99 能夠加快編譯速度,而且顯示全部信息,
在編譯的時候,個人swap被佔滿,而且報錯,多是由於屏幕上刷的太快致使的:
virtual memory exhaustedvirtual memory exhausted
不打開V=99的狀況下,個人編譯log以下:
tan@ubuntu:~/openwrt$ make -j4 make[1] world make[2] target/compile make[2] package/cleanup make[3] -C target/linux compile make[2] package/compile make[3] -C package/system/opkg host-compile make[3] -C package/libs/toolchain compile make[3] -C package/kernel/gpio-button-hotplug compile make[3] -C package/libs/ncurses host-compile make[3] -C package/libs/libnl-tiny compile make[3] -C package/utils/lua compile make[3] -C package/libs/libjson-c compile make[3] -C package/libs/lzo compile make[3] -C package/libs/zlib compile make[3] -C package/libs/ncurses compile make[3] -C package/boot/uboot-ar71xx compile make[3] -C package/firmware/linux-firmware compile make[3] -C package/libs/ocf-crypto-headers compile make[3] -C package/network/utils/iw compile make[3] -C package/network/services/dropbear compile make[3] -C package/libs/libpcap compile make[3] -C package/network/utils/linux-atm compile make[3] -C package/network/utils/resolveip compile make[3] -C package/utils/busybox compile make[3] -C package/libs/libubox compile make[3] -C package/utils/util-linux compile make[3] -C package/kernel/linux compile make[3] -C package/libs/openssl compile make[3] -C package/system/ubus compile make[3] -C package/system/uci compile make[3] -C package/utils/jsonfilter compile make[3] -C package/system/mtd compile make[3] -C package/system/opkg compile make[3] -C package/network/config/netifd compile make[3] -C package/system/ubox compile make[3] -C package/utils/ubi-utils compile make[3] -C package/network/services/hostapd compile make[3] -C package/network/config/swconfig compile make[3] -C package/network/services/odhcpd compile make[3] -C package/network/utils/iwinfo compile make[3] -C package/system/procd compile make[3] -C package/system/fstools compile make[3] -C package/base-files compile make[3] -C package/boot/uboot-envtools compile make[3] -C package/kernel/mac80211 compile make[3] -C package/network/utils/iptables compile make[3] -C package/network/services/dnsmasq compile make[3] -C package/network/ipv6/odhcp6c compile make[3] -C package/network/services/ppp compile make[3] -C package/network/config/firewall compile make[2] package/install make[3] package/preconfig make[2] target/install make[3] -C target/linux install make[2] package/index
最終會生成下面的文件(在bin文件夾內):
因爲我使用默認的配置,生成的文件太多,這裏只給一個部分的截圖
初次下載源代碼,爲了理解openwrt的架構和編譯過程,下面作一下簡要的分析:
openwrt是基於linux kernel的,而且使用uclibc做爲c庫。
注意到編譯過程當中生成了三個文件夾,那麼他們分別是幹什麼的呢?
dl
build_dir
staging_dir
dl是在編譯的時候下載文件的目錄,這些文件都是編譯所須要的,下面是它們的的一部分:
├── ath10k-firmware-da0f85d924226ee30c46e037120621c9e192b39e.tar.bz2 ├── autoconf-2.69.tar.xz ├── automake-1.15.tar.xz ├── bc-1.06.95.tar.bz2 ├── binutils-linaro-2.24.0-2014.09.tar.xz ├── bison-3.0.2.tar.xz ├── broadcom-wl-4.150.10.5.tar.bz2 ├── broadcom-wl-5.100.138.tar.bz2 ├── busybox-1.23.2.tar.bz2 ├── cmake-2.8.12.2.tar.gz ├── compat-wireless-2015-03-09.tar.bz2 ├── dnsmasq-2.72.tar.gz ├── dropbear-2014.65.tar.bz2 ├── e2fsprogs-1.42.8.tar.gz ├── findutils-4.4.2.tar.gz ├── firewall-2015-02-26-165029cb8c0f1545628f44143aec965e64cef021.tar.gz ├── flex-2.5.39.tar.bz2 ├── fstools-2015-03-30-a5fa5b6144253726dcd7e769197eed787a723f5f.tar.gz ├── gcc-linaro-4.8-2014.04.tar.xz ├── gdb-linaro-7.6-2013.05.tar.bz2 ├── genext2fs-1.4.1.tar.gz ├── gengetopt-2.22.6.tar.gz ├── gmp-5.1.3.tar.xz ├── hostapd-2015-03-25.tar.bz2 ├── iptables-1.4.21.tar.bz2 ├── ipw2100-fw-1.3.tgz ├── ipw2200-fw-3.1.tgz ├── iw-3.17.tar.xz ├── json-c-0.12.tar.gz ├── jsonfilter-2014-06-19-cdc760c58077f44fc40adbbe41e1556a67c1b9a9.tar.gz ├── libelf-0.8.13.tar.gz ├── libiwinfo-2015-03-23-40f2844fadc05f4a4de7699dbc12fee295b7057b.tar.gz ├── libpcap-1.5.3.tar.gz ├── libtool-2.4.tar.gz ├── libubox-2015-03-22-b8d9b382e39823850331edc2a92379173daf1be3.tar.gz ├── linux-3.18.10.tar.xz ├── linux-atm-2.5.2.tar.gz ├── linux-firmware-2015-03-20-f404336ba808cbd57547196e13367079a23b822c.tar.bz2 ├── lua-5.1.5.tar.gz
注意到,這些都是從網上下載的,要注意保留,之後編譯的時候就不用上網下載了。
而build_dir
的做用就是存放上述這些壓縮包的解壓路徑,也就是說,dl的包會解壓到build_dir
裏面,
而且編譯這些包。
其中,這裏有三個目錄:
tan@ubuntu:~/openwrt$ tree build_dir/ -d -L 1 build_dir/ ├── host ├── target-mips_34kc_uClibc-0.9.33.2 └── toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2
host目錄是爲了編譯一些tools用於協助生成openwrt image
target目錄是爲目標主機編譯用的,能夠在目錄上看到CPU的架構和所用的c庫
toolchain是用來編譯交叉編譯器的
在staging_dir下面能夠看到相似的三個目錄:
tan@ubuntu:~/openwrt$ tree staging_dir/ -d -L 1 staging_dir/ ├── host ├── target-mips_34kc_uClibc-0.9.33.2 └── toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2
host目錄下存放了一些編譯主機上的一些工具(tools)
target 目錄主要存放編譯出來的firmware,是給目標機器用的
toolchain目錄包含了交叉編譯器,你能夠在裏面寫一個簡單的c文件,而且使用交叉編譯器編譯它,
生成的程序能夠在目標機器上運行。
雖然不徹底如此,能夠將staging_dir的每一個文件夾對應理解成build_dir的產物
這裏有編譯過程的大致介紹:
http://wiki.openwrt.org/doc/howto/build
http://downloads.openwrt.org/docs/buildroot-documentation.html
openwrt是一個高度定製版的buildroot,官網有它的介紹:
http://wiki.openwrt.org/about/toolchain
使用這個系統,能夠基本作到全自動的編譯過程。
bin目錄下面的文件粗看能夠分爲兩類:
openwrt-ar71xx-generic-a02-rb-w300n-squashfs-factory.bin
openwrt-ar71xx-generic-a02-rb-w300n-squashfs-sysupgrade.bin
其中這兩個的區別是(轉自http://see.sl088.com/wiki/Openwrt_factory%E5%9B%BA%E4%BB%B6/%E4%B8%BA%E4%BD%95%E5%85%88%E5%88%B7factory):
factory是用來從原廠固件升級到openwrt用的。 sysupgrade是用來給openwrt升級用的
不管你是升級仍是從官方方刷openwrt,openwrt-XXXXXXX-factory.bin的固件都是適用的。 而openwrt-XXXXXXX-sysupgrade.bin.固件只能用來升級用。如TTL救磚就不能用sysupgrade的固件。
其中這裏又進一步說明了:
http://www.cnblogs.com/siikee/p/4224086.html
bin文件下還有不少ipk文件,這些文件是opkg包管理系統的文件,在openwrt
運行起來的時候可使用opkg安裝,用起來和debian的deb差很少。
另外,openwrt 官方說了,the bootloader is not part of OpenWrt
http://wiki.openwrt.org/doc/techref/bootloader
並且,bootloader對於每個路由器都是不同的,負責將最底層開起來。廠家也不見得會將最底層的
代碼開源。
目前有不少賣修改好的openwrt路由器,一個賣點就是不死uboot,就是說
你的firmware無論怎麼刷均可以恢復,它包括一個網頁接口,能夠上傳firmware
到路由器上,這樣大大方便了openwrt的調試。
openwrt的menuconfig是定製好的,項目在config**.in裏面:
最後看看openwrt 的patch系統
package的不少子目錄都包含這兩個東西,patches 是一些patch,Makefile包含了下載地址和其餘的一些信息。
當發現這些用戶空間軟件出問題的時候,爲其加patch就能夠了,
實際上linux kernel出問題時,也能夠這樣相似地對其加一些patch進去。