Busybox 1.17.4 編譯及錯誤解決方案
#vim Makefile
找到OSS_COMPILE ?=
修改為:CROSS_COMPILE=/usr/local/arm/3.4.1/bin/arm-linux-
也可以執行make menuconfig,進入配置介面來配置,這樣做的前提是必須在$PATH中已添加了交叉編譯gcc
#make menuconfig
進入“Busybox Settings ——>”
“Build options ---->”
選擇( ) Cross Compiler prefix 輸入arm-linux-
2.2 使用預設配置進行編譯
#make defconfig
會有一些預設的選項配置,同時需要修改以下選項,以避免出現一些錯誤:
· Busybox Settings --->
· Build Options --->
· [*] Build BusyBox as a static binary (no shared libs) //這裡編譯為靜態庫
· [ ] Build with Large File Support //這裡要去掉這一項
· () Cross Compiler perfix //設定交叉編譯器路徑
· Installation Options --->
· [*] Don't use /usr //不安裝到系統的usr目錄下,以解壓目錄下的_install來代替
· Linux System Utilities --->
· [ ] mkfs_ext2
· [ ] mkfs_vfat //這兩項不選,否則編譯會報錯
然後make,
通常會有一些錯誤,我們的目標是先通過編譯。所以對下面幾個錯誤採用最簡便的辦法處理通過。
#make
miscutils/ionice.c: In function `ioprio_set':
miscutils/ionice.c:16: error: `SYS_ioprio_set' undeclared (first use in this function)
miscutils/ionice.c:16: error: (Each undeclared identifier is reported only once
miscutils/ionice.c:16: error: for each function it appears in.)
miscutils/ionice.c: In function `ioprio_get':
miscutils/ionice.c:21: error: `SYS_ioprio_get' undeclared (first use in this function)
make[1]: *** [miscutils/ionice.o] Error 1
make: *** [miscutils] Error 2
將引起錯誤的功能去掉,這個ionice的位置:
Miscellaneous Utilities --->
[ * ] ionice
重新make ,出現第2次make 錯誤:
#make
networking/interface.c:807: error: `ARPHRD_INFINIBAND' undeclared here (not in a function)
networking/interface.c:807: error: initializer element is not constant
networking/interface.c:807: error: (near initialization for `ib_hwtype.type')
make[1]: *** [networking/interface.o] Error 1
make: *** [networking] Error 2
在出錯位置看一下原始碼,發現:
#if ENABLE_FEATURE_HWIB
……
由於跟infiniband 沒啥關係,不如關閉這個:ENABLE_FEATURE_HWIB
在.config 中直接關掉,或者到make menuconfig中關掉:
Busybox Settings--->
Busybox Library Tuning-->
[]Support infiniband HW
第3次make錯誤:
#make
networking/libiproute/ipaddress.c: In function `print_linkinfo':
networking/libiproute/ipaddress.c:167: error: `IFLA_OPERSTATE' undeclared (first use in this function)
networking/libiproute/ipaddress.c:167: error: (Each undeclared identifier is reported only once
networking/libiproute/ipaddress.c:167: error: for each function it appears in.)
make[1]: *** [networking/libiproute/ipaddress.o] Error 1
make: *** [networking/libiproute] Error 2
找到原始碼位置,
我們對程式碼做如下修改:networking/libiproute/ipaddress.c
printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MAST ER]), b1));
165 }
166 #endif
//在這裡新增巨集判斷:
#ifdef IFLA_OPERSTATE
167 if (tb[IFLA_OPERSTATE]) {
168 static const char operstate_labels[] ALIGN1 =
169 "UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0"
170 "TESTING\0""DORMANT\0""UP\0";
171 printf("state %s ", nth_string(operstate_labels,
172 *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTA TE])));
173 }
#endif //這裡新增巨集結束
174if (G_filter.showqueue)
第4次編譯,成功:
CC util-linux/volume_id/romfs.o
CC util-linux/volume_id/sysv.o
CC util-linux/volume_id/udf.o
CC util-linux/volume_id/util.o
CC util-linux/volume_id/volume_id.o
CC util-linux/volume_id/xfs.o
AR util-linux/volume_id/lib.a
LINK busybox_unstripped
Trying libraries: crypt m
Library crypt is not needed, excluding it
Library m is needed, can't exclude it (yet)
Final link with: m
DOC busybox.pod
DOC BusyBox.txt
DOC BusyBox.1
DOC BusyBox.html
附:
如果Linux System Utilities --->
· [*] mkfs_ext2
· [ *] mkfs_vfat //如果這兩項選上,編譯會報錯如下:
In file included from /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include/linux/cache.h:4,
from /usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../../../../arm-linux/sys-include/linux/fs.h:18,
from util-linux/mkfs_ext2.c:11:
/usr/local/arm/3.4.1/lib/gcc/arm-linux/3.4.1/../.
繼續編譯,發現還是有錯誤:
networking/libiproute/ipaddress.c:167: error: `IFLA_OPERSTATE' undeclared (first use in this function)
這個錯誤其實是busybox的一個bug,一直未解決,我們對程式碼做如下修改:
- 164 164 printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
- 165 165 }
- 166 166 #endif
- 167 #ifdef IFLA_OPERSTATE
- 167 168 if (tb[IFLA_OPERSTATE]) {
- 168 169 staticconstchar operstate_labels[] ALIGN1 =
- 169 170 "UNKNOWN/0""NOTPRESENT/0""DOWN/0""LOWERLAYERDOWN/0"
- … …
- 171 172 printf("state %s ", nth_string(operstate_labels,
- 172 173 *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE])));
- 173 174 }
- 175 #endif
- 174 176 if (G_filter.showqueue)
- 175 177 print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));
- 176 178
- *
- 274 274 return ipaddr_list_or_flush(argv, 0);
- 275 275 }
- 276 276
- 277 #ifdef IFLA_LINKINFO
- 277 278 #ifndef NLMSG_TAIL
- 278 279 #define NLMSG_TAIL(nmsg) /
- 279 280 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
- … …
- 360 361 return 2;
- 361 362 return 0;
- 362 363 }
- 364 #endif
- 363 365
- 364 366 /* Return value becomes exitcode. It's okay to not return at all */
- 365 367 int do_iplink(char **argv)
- 366 368 {
- 367 369 staticconstchar keywords[] ALIGN1 =
- 370 #ifdef IFLA_LINKINFO
- 368 371 "add/0""delete/0""set/0""show/0""lst/0""list/0";
- 372 #else
- 373 "set/0""show/0""lst/0""list/0";
- 374 #endif
- 369 375 if (*argv) {
- 370 376 smalluint key = index_in_substrings(keywords, *argv);
- 371 377 if (key > 5) /* invalid argument */
- 372 378 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
- 373 379 argv++;
- 380 #ifdef IFLA_LINKINFO
- 374 381 if (key <= 1) /* add/delete */
- 375 382 return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
- 376 383 elseif (key == 2) /* set */
- 384 #else
- 385 if (key == 0) /* set */
- 386 #endif
- 377 387 return do_set(argv);
- 378 388 }
- 379 389 /* show, lst, list */
完成後繼續編譯
執行 make install,終於在_install資料夾下生成了工具包
4、製作檔案系統
可以先建立一個工作目錄,如myroot,在工作目錄下 建立以下目錄:bin sbin dev etc lib home root usr var proc mnt tmp sys
執行 mkdir bin sbin dev etc lib home root usr var proc mnt tmp sys
在etc 下面要寫兩個檔案fstab inittab 和一個資料夾init.d
(a) fstab 的內容是:
- proc /proc proc defaults 0 0
- tmpfs /tmp tmpfs defaults 0 0
- sysfs /sys sysfs defaults 0 0
- tmpfs /dev tmpfs defaults 0 0
(b) fstab 檔案的作用
文 件/etc/fstab 存放的是系統中的檔案系統資訊。當正確的設定了該檔案,則可以通過"mount /directoryname"命令來載入一個文 件系統,每種檔案系統都對應一個獨立的行,每行中的欄位都有空格或tab 鍵分開。同時fsck、mount 、umount 的等命令都利用該程式。
inittab 的內容是:
- #/etc/inittab
- ::sysinit:/etc/init.d/rcS
- ::askfirst:-/bin/sh
- ::ctrlaltdel:/sbin/reboot
- ::shutdown:/bin/umount -a -r
(c) init.d/rcS 檔案的內容:
- #!/bin/sh
- ifconfig eth0 192.168.1.17
- mount -t tmpfs mdev /dev
- mkdir /dev/pts
- mount -t devpts devpts /dev/pts
- mount -t sysfs sysfs /sys
- mount -a
- echo /sbin/mdev > /proc/sys/kernel/hotplug
- mdev –s
- echo leohui1988_busybox
(d)在/dev 下建立裝置節點:Console null
- mknod dev/console c 5 1
- mknod dev/null c 1 3
(e)將編譯busybox生成的/bin和/sbin下的工具拷貝到myroot下的/bin和/sbin下
(f)使用mkyaffs2image製作yaffs檔案系統映象
./mkyaffs2image myroot rootfs.yaffs
將yaffs燒寫至開發板,可在終端下看到leohui1988_busybox的輸出,最基本的檔案系統製作成功!
注意:
如果使用靜態編譯,那麼後面我們移植到開發板的程式也必須靜態編譯,這樣的話就比較佔儲存空間,為此可以將busybox進行動態編譯,使用共享連結庫來減小體積,同時也方便後面程式進行編譯和移植。
動態編譯步驟與以上類似,只是把 [ ] Build BusyBox as a static binary (no shared libs)這一項替換掉。其餘步驟一樣,完成後將bin和sbin拷貝到檔案系統的bin,sbin下,然後將linuxrc這個連結檔案也拷入檔案系統根目錄下,最初我沒放linuxrc這個連結檔案時,啟動顯示init錯誤。之後再將arm-linux交叉編譯工具的lib(我的路徑是/usr/local/arm/3.4.1/arm-linux/lib)庫拷貝到檔案系統lib下。製作成映象燒寫至flash,啟動成功!
2.3 生成根檔案系統必需檔案:
#make install
會在當前busybox 目錄下生成_install子目錄,目錄下生成bin, sbin, usr三個子目錄,並且生成linuxrc檔案