1. 程式人生 > >Busybox 1.17.4 編譯及錯誤解決方案

Busybox 1.17.4 編譯及錯誤解決方案

2.1 Makefile中新增編譯工具:
#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,一直未解決,我們對程式碼做如下修改:

  1. 164 164                 printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));   
  2. 165 165         }   
  3. 166 166 #endif   
  4.     167 #ifdef IFLA_OPERSTATE   
  5. 167 168         if (tb[IFLA_OPERSTATE]) {   
  6. 168 169                 staticconstchar operstate_labels[] ALIGN1 =   
  7. 169 170                         "UNKNOWN/0""NOTPRESENT/0""DOWN/0""LOWERLAYERDOWN/0"
  8. …   …      
  9. 171 172                 printf("state %s ", nth_string(operstate_labels,   
  10. 172 173                                         *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE])));   
  11. 173 174         }   
  12.     175 #endif   
  13. 174 176         if (G_filter.showqueue)   
  14. 175 177                 print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));   
  15. 176 178    
  1. *  
  2.   274   274         return ipaddr_list_or_flush(argv, 0);   
  3.   275   275 }   
  4.   276   276    
  5.     277 #ifdef IFLA_LINKINFO   
  6.   277   278 #ifndef NLMSG_TAIL   
  7.   278   279 #define NLMSG_TAIL(nmsg) /   
  8.   279   280         ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))   
  9.   …     …      
  10.   360   361                 return 2;   
  11.   361   362         return 0;   
  12.   362   363 }   
  13.     364 #endif   
  14.   363   365    
  15.   364   366 /* Return value becomes exitcode. It's okay to not return at all */
  16.   365   367 int do_iplink(char **argv)   
  17.   366   368 {   
  18.   367   369         staticconstchar keywords[] ALIGN1 =   
  19.     370 #ifdef IFLA_LINKINFO   
  20.   368   371                 "add/0""delete/0""set/0""show/0""lst/0""list/0";   
  21.     372 #else
  22.     373                 "set/0""show/0""lst/0""list/0";   
  23.     374 #endif   
  24.   369   375         if (*argv) {   
  25.   370   376                 smalluint key = index_in_substrings(keywords, *argv);   
  26.   371   377                 if (key > 5) /* invalid argument */
  27.   372   378                         bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);   
  28.   373   379                 argv++;   
  29.     380 #ifdef IFLA_LINKINFO   
  30.   374   381                 if (key <= 1) /* add/delete */
  31.   375   382                         return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);   
  32.   376   383                 elseif (key == 2) /* set */
  33.     384 #else
  34.     385                 if (key == 0) /* set */
  35.     386 #endif   
  36.   377   387                         return do_set(argv);   
  37.   378   388         }   
  38.   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 的內容是:

  1. proc /proc proc defaults 0 0  
  2. tmpfs /tmp tmpfs defaults 0 0  
  3. sysfs /sys sysfs defaults 0 0  
  4. tmpfs /dev tmpfs defaults 0 0  

(b) fstab 檔案的作用

文 件/etc/fstab 存放的是系統中的檔案系統資訊。當正確的設定了該檔案,則可以通過"mount /directoryname"命令來載入一個文 件系統,每種檔案系統都對應一個獨立的行,每行中的欄位都有空格或tab 鍵分開。同時fsckmount 、umount 的等命令都利用該程式。

inittab 的內容是:

  1. #/etc/inittab
  2. ::sysinit:/etc/init.d/rcS  
  3. ::askfirst:-/bin/sh   
  4. ::ctrlaltdel:/sbin/reboot  
  5. ::shutdown:/bin/umount -a -r  

(c) init.d/rcS 檔案的內容:

  1. #!/bin/sh
  2. ifconfig eth0 192.168.1.17  
  3. mount -t tmpfs mdev /dev  
  4. mkdir /dev/pts  
  5. mount -t devpts devpts /dev/pts  
  6. mount -t sysfs sysfs /sys  
  7. mount -a  
  8. echo /sbin/mdev > /proc/sys/kernel/hotplug  
  9. mdev –s  
  10. echo leohui1988_busybox  

(d)在/dev 下建立裝置節點:Console null

  1. mknod dev/console c 5 1  
  2. 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檔案