Hi3531 软件环境搭建

Posted q123456789098

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hi3531 软件环境搭建相关的知识,希望对你有一定的参考价值。


第二章 首次安装SDK

1、Hi3531 SDK包位置
    在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx.x.x.x.tgz 的文件,
该文件就是Hi3531的软件开发包。

2、解压缩SDK包
    在linux服务器上(或者一台装有linux的PC上,主流的linux发行版本均可以),使用命令:tar -zxf Hi3531_SDK_Vx.x.x.x.tgz ,
解压缩该文件,可以得到一个Hi3531_SDK_Vx.x.x.x目录。

3、展开SDK包内容

    返回Hi3531_SDK_Vx.x.x.x目录,运行./sdk.unpack(请用root或sudo权限执行)将会展开SDK包打包压缩存放的内容,请按照提示完成操作。

如果您需要通过WINDOWS操作系统中转拷贝SDK包,请先运行./sdk.cleanup,收起SDK包的内容,拷贝到新的目录后再展开。

遇到以下问题:

[email protected]:~/product$ tar -zxf Hi3531_SDK_V1.0.8.0.tgz 
[email protected]:~/product$ ls
a8_orig          c300.tar.bz2  Hi3531_SDK_V1.0.8.0      netconfig~
a8_orig.tar.bz2  c318          Hi3531_SDK_V1.0.8.0.tgz  pingloop~
app_init         gis           mysql_hotbackup          pings
app_init~        gislinux.tar  mysql-setup.sh           pings~
app_init2        gis.tar.gz    netcfg                   record
c300             gis_udblip    netconfig                record.tar.bz2
[email protected]:~/product$ cd Hi3531_SDK_V1.0.8.0
[email protected]:~/product/Hi3531_SDK_V1.0.8.0$ ls
package  scripts  sdk.cleanup  sdk.unpack
[email protected]:~/product/Hi3531_SDK_V1.0.8.0$ sudo ./sdk.unpack
[sudo] password for a: 
./sdk.unpack: 2: ./sdk.unpack: source: not found
./sdk.unpack: 4: ./sdk.unpack: ECHO: not found
./sdk.unpack: 6: ./sdk.unpack: WARN: not found
./sdk.unpack: 7: ./sdk.unpack: WARN: not found
./sdk.unpack: 8: ./sdk.unpack: ECHO: not found
./sdk.unpack: 20: ./sdk.unpack: ECHO: not found
./sdk.unpack: 22: ./sdk.unpack: run_command_progress_float: not found
./sdk.unpack: 24: ./sdk.unpack: ECHO: not found
mkdir: created directory ‘mpp’
./sdk.unpack: 26: ./sdk.unpack: run_command_progress_float: not found
./sdk.unpack: 28: ./sdk.unpack: ECHO: not found
mkdir: created directory ‘drv’
./sdk.unpack: 30: ./sdk.unpack: run_command_progress_float: not found
解决方案

 1)Ubuntu下修改默认Shell:dash为bash
输入 dpkg-reconfigure dash 后选 no 选项

2)解压SDK到当前目录后 进入目录如: ./Hi3515_V100R001C01SPC050/software/board
解压 tar zxvf Hi3515_SDK_V1.0.5.0.c1.tgz
进入目录,找到 scripts/common.sh
vi scripts/common.sh
找到 run_command_progress_float() 函数
将其中的:
prog_bar_base="[    ]"
while [ $rcp_tmp -lt $RCP_RANGE ]
do
prog_bar_base="$prog_bar_base-"
((rcp_tmp++)) 
done
替换为
prog_bar_base="[    ]"
while [ $rcp_tmp -lt $RCP_RANGE ]
do
prog_bar_base="$prog_bar_base-"
                ((rcp_tmp=rcp_tmp+1))
done
主要就是将第159行的((rcp_tmp++))替换为((rcp_tmp=rcp_tmp+1))
保存退出

3)如果用一般用户编译,需在用户的主目录的./baserc文件中最后增加编译器路径:
vi ~/.bashrc
文件末尾位置加入:
export PATH="$PATH:/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/:/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/bin/"
保存退出
然后:
sudo vi /root/.bashrc
仍在文件末尾位置加入:
export PATH="$PATH:/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/:/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/bin/"
保存退出
如用root编译可不做上述工作
4)普通用户编译执行
sudo ./sdk.unpack

SDK编译成功!

修改后输出结果

[email protected]:~/product/Hi3531_SDK_V1.0.8.0$ sudo ./sdk.unpack
Unpacking SDK
WARN: Be sure you have installed the cross-compiler. if not, install it first!
WARN: ALL THE SOUCE FILES WILL BE OVERWRITED, FILES YOU MOTIFIED WILL BE LOST !!!

unpacking osdrv
run_command_progress_float: 'tar -xvzf package/osdrv.tgz'
[100%]##################################################|
unpacking mpp
run_command_progress_float: 'tar -xvzf package/mpp.tgz'
[100%]##################################################|
unpacking drv
run_command_progress_float: 'tar -xvzf package/drv.tgz'
[100%]##################################################|




4、在linux服务器上安装交叉编译器

    1)安装uclibc交叉编译器(注意,需要有sudo权限或者root权限):
       进入Hi3531_SDK_Vx.x.x.x/osdrv/toolchain/arm-hisiv100-linux目录,运行chmod +x cross.install,然后运行./cross.install即可。
    2) 安装glibc交叉编译器(注意,需要有sudo权限或者root权限):

       进入Hi3531_SDK_Vx.x.x.x/osdrv/toolchain/arm-hisiv200-linux目录,运行chmod +x cross.install,然后运行./cross.install即可。

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/toolchain/arm-hisiv200-linux$ sudo chmod +x cross.install
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/toolchain/arm-hisiv200-linux$ sudo ./cross.install
CROSS_COMPILER_PATH=/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin
Do not have version file
mkdir: created directory ‘/opt/hisi-linux’
mkdir: created directory ‘/opt/hisi-linux/x86-arm’
mkdir: created directory ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux’
Extract cross tools ...
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-addr2line’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-addr2line’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-ar’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-ar’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-as’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-as’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-c++’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-c++’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-c++filt’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-c++filt’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-cpp’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-cpp’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-g++’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-g++’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gcc’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gcc’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gcc-4.4.1’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gcc-4.4.1’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gccbug’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gccbug’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gcov’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gcov’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gdb’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gdb’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gdbtui’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gdbtui’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-gprof’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-gprof’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-ld’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-ld’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-nm’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-nm’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-objcopy’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-objcopy’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-objdump’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-objdump’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-ranlib’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-ranlib’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-readelf’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-readelf’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-size’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-size’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-strings’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-strings’
‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin/arm-hisiv200-linux-strip’ -> ‘/opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/arm-hisiv200-linux-gnueabi-strip’
export path /opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin



    3) 执行source /etc/profile, 安装交叉编译器的脚本配置的环境变量就可以生效了,或者请重新登陆也可。
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/toolchain/arm-hisiv200-linux$  source /etc/profile


export PATH="$PATH:/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/usr/bin/:/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin"
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/kernel/linux-3.0.y$ sudo make ARCH=arm CROSS_COMPILE=arm-hisiv200-linux- uImage  
make: arm-hisiv200-linux-gcc: Command not found
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
  CC      kernel/bounds.s
/bin/sh: arm-hisiv200-linux-gcc: command not found
make[1]: *** [kernel/bounds.s] Error 127
make: *** [prepare0] Error 2
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/kernel/linux-3.0.y$ arm-hisiv200-linux-gcc
arm-hisiv200-linux-gcc: no input files

先build uboot

    make ARCH=arm CROSS_COMPILE=arm-hisiv200-linux- godnet_config

    make ARCH=arm CROSS_COMPILE=arm-hisiv200-linux-
UNDEF_SYM=`arm-hisiv200-linux-objdump -x board/godnet/libgodnet.a lib/libgeneric.a lib/lzma/liblzma.a lib/lzo/liblzo.a arch/arm/cpu/godnet/libgodnet.a 
arch/arm/cpu/godnet/godnet/libgodnet.a arch/arm/lib/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a 
fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a fs/ubifs/libubifs.a net/libnet.a disk/libdisk.a drivers/bios_emulator/libatibiosemu.a
 drivers/block/libblock.a drivers/dma/libdma.a drivers/fpga/libfpga.a drivers/gpio/libgpio.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a 
drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/onenand/libonenand.a
 drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/mtd/spi/hisfc350/libhisfcv350.a drivers/mtd/spi/hisfc300new/libhisfcv300new.a 
drivers/net/libnet.a drivers/net/phy/libphy.a drivers/net/hisfv300/libhisfv300.a drivers/net/higmac/libhigmac.a drivers/net/stmmac/libstmmac.a 
drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/power/libpower.a drivers/spi/libspi.a drivers/vo/libvo.a drivers/hdmi/libhdmi.a 
drivers/dec/libjpegd.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/twserial/libtws.a drivers/usb/gadget/libusb_gadget.a 
drivers/usb/host/libusb_host.a drivers/usb/host/hiusb/libhiusb.a drivers/usb/musb/libusb_musb.a drivers/usb/phy/libusb_phy.a 
drivers/video/libvideo.a drivers/watchdog/libwatchdog.a common/libcommon.a lib/libfdt/libfdt.a api/libapi.a post/libpost.a product/libproduct.a 
product/hiupdate/libhiupdate.a | sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;
 cd /home/a/product/Hi3531_SDK_V1.0.8.0/osdrv/uboot/u-boot-2010.06 && arm-hisiv200-linux-ld -Bstatic -T u-boot.lds 
 -Ttext 0x80800000 $UNDEF_SYM arch/arm/cpu/godnet/start.o --start-group lib/libgeneric.a lib/lzma/liblzma.a lib/lzo/liblzo.a 
arch/arm/cpu/godnet/libgodnet.a arch/arm/cpu/godnet/godnet/libgodnet.a arch/arm/lib/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a 
fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a fs/ubifs/libubifs.a net/libnet.a disk/libdisk.a 
drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/fpga/libfpga.a drivers/gpio/libgpio.a 
drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a 
drivers/mtd/nand/libnand.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a 
drivers/mtd/spi/hisfc350/libhisfcv350.a drivers/mtd/spi/hisfc300new/libhisfcv300new.a drivers/net/libnet.a drivers/net/phy/libphy.a 
drivers/net/hisfv300/libhisfv300.a drivers/net/higmac/libhigmac.a drivers/net/stmmac/libstmmac.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a 
drivers/power/libpower.a drivers/spi/libspi.a drivers/vo/libvo.a drivers/hdmi/libhdmi.a drivers/dec/libjpegd.a drivers/rtc/librtc.a 
drivers/serial/libserial.a drivers/twserial/libtws.a drivers/usb/gadget/libusb_gadget.a drivers/usb/host/libusb_host.a drivers/usb/host/hiusb/libhiusb.a
 drivers/usb/musb/libusb_musb.a drivers/usb/phy/libusb_phy.a drivers/video/libvideo.a drivers/watchdog/libwatchdog.a common/libcommon.a
 lib/libfdt/libfdt.a api/libapi.a post/libpost.a product/libproduct.a product/hiupdate/libhiupdate.a board/godnet/libgodnet.a --end-group
 /home/a/product/Hi3531_SDK_V1.0.8.0/osdrv/uboot/u-boot-2010.06/arch/arm/lib/eabi_compat.o 
-L /opt/hisi-linux/x86-arm/arm-hisiv200-linux/bin/../lib/gcc/arm-hisiv200-linux-gnueabi/4.4.1 -lgcc -Map u-boot.map -o u-boot
arm-hisiv200-linux-objcopy -O srec u-boot u-boot.srec
arm-hisiv200-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin



然后把uboot的tools加入path文件

export PATH="$PATH:/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/usr/bin/:/opt/hisi-linux/x86-arm/arm-hisiv200-linux/target/bin:/home/a/product/Hi3531_SDK_V1.0.8.0/osdrv/uboot/u-boot-2010.06/tools"



  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-3.0.8
Created:      Mon May 23 02:31:49 2016
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    3496792 Bytes = 3414.84 kB = 3.33 MB
Load Address: 80008000
Entry Point:  80008000
  Image arch/arm/boot/uImage is ready

编译busybox

a. 修改一下源码
    [email protected]:/work/busybox/busybox-1.20.2$ vi include/libbb.h 
   添加一行  #include  <sys/resource.h>
要不会出现如下错误:
    loginutils/passwd.c: In function ‘passwd_main’:
    loginutils/passwd.c:104:16: error: storage size of ‘rlimit_fsize’ isn’t known
    loginutils/passwd.c:188:12: error: ‘RLIMIT_FSIZE’ undeclared (first use in this function)
    loginutils/passwd.c:188:12: note: each undeclared identifier is reported> each function it appears in
    loginutils/passwd.c:104:16: warning: unused variable ‘rlimit_fsize’ [-Wunused-variable]
配置busybox
    [email protected]:/work/busybox/busybox-1.20.2$ make menuconfig
    Busybox Setting -> Build Options
           [*]Build BusyBox as a static binary(no shared libs)  //一定要选上这个,这样busybox才不依赖于其它的东东,独立运行的
    Build Options  --->    
          (/work/busybox/arm-2012.09/bin/arm-none-linux-gnueabi-) Cross Compiler prefix //配置工具链
c. make  //只make,不用 make install 
这会在当前目录下生成 busybox
    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


d make install
  ./_install/usr/sbin/setlogcons -> ../../bin/busybox
  ./_install/usr/sbin/svlogd -> ../../bin/busybox
  ./_install/usr/sbin/telnetd -> ../../bin/busybox
  ./_install/usr/sbin/udhcpd -> ../../bin/busybox


   --------------------------------------------------
   You will probably need to make your busybox binary
   setuid root to ensure all configured applets will
   work properly.
   --------------------------------------------------


根文件系统的制作和使用

===========================================================================

启动时用到initrd来mount根文件系统。注意理解ramdisk和initrd这两个概念,其实ramdisk只是在ram上实现的块设备,类似与硬盘操作,但有更快的读写速度,它可以在
系统运行的任何时候使用,而不仅仅是用于启动;initrd(boot loader initialized RAM disk)可以说是启动过程中用到的一种机制,具体的实现过程也使用ramdisk技术。
就是在装载linux之前,bootloader可以把一个比较小的根文件系统的映象装载在内存的某个指定位置,姑且把这段内存称为initrd(这里是initrd所占的内存,不是ramdisk,
注意区别),然后bootloader通过传递参数的方式告诉内核initrd的起始地址和大小(也可以把这些参数编译在内核中),在启动阶段就可以暂时的用initrd来mount根文件
系统。initrd的最初的目的是为了把kernel的启动分成两个阶段:在kernel中保留最少最基本的启动代码,然后把对各种各样硬件设备的支持以模块的方式放在initrd中,
这样就在启动过程中可以从initrd所mount的根文件系统中装载需要的模块。这样的一个好处就是在保持kernel不变的情况下,通过修改initrd中的内容就可以灵活的支持
不同的硬件。在启动完成的最后阶段,根文件系统可以重新mount到其他设备上,但是也可以不再 重新mount(很多嵌入式系统就是这样)。 initrd的具体实现过程是这样的:
bootloader把根文件系统映象装载到内存指定位置,把相关参数传递给内核,内核启动时把initrd中的内容复制到ramdisk中(ram0),把initrd占用的内存释放掉,
在ram0上mount根文件系统。从这个过程可以看出,内核需要对同时对ramdisk和initrd的支持(这种需要都编入内核,不能作为模块)。 
这四种给rootfs提供内容的方式都有一个共同点:在kernel启动时,一系列的文件被解压到rootfs,如果kernel能在其中找到可执行的文件“/init”,kernel就会运行它;
这意味着,kernel不会再去理会“root=”是指向哪里的。此外,一旦initramfs里面的init 进程运行起来,kernel就会认为启动已经完成
使用initramfs最简单的方式,莫过于用已经做好的cpio.gz把kernel里面那个空的给换掉。这是2.6 kernel天生支持的,所以,你不用做什么特殊的设置。
kernel的config option里面有一项CONFIG_INITRAMFS_SOURCE(I.E. General setup--->Initramfs source file(s) in menuconfig)。
这个选项指向放着内核打包initramfs</p><p>需要的所有文件。默认情况下,这个选项是留空的,所以内核编译出来之后initramfs也就是空的,
也就是前面提到的rootfs什么都不做的情形。</p>CONFIG_INITRAMFS_SOURCE 可以是一个绝对路径,也可以是一个从kernel’s top build dir
(你敲入build或者是make的地方)开始的相对路径。而指向的目标可以有以下三<p>种:一个已经做好的cpio.gz,或者一个已经为制作cpio.gz准备好所有内容的文件夹,
或者是一个text的配置文件。
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/kernel/linux-3.0.y# cat .config |grep CONFIG_INITRAMFS_SOURCE
CONFIG_INITRAMFS_SOURCE=""
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/kernel/linux-3.0.y# cat .config |grep CONFIG_INITRAMFS_SOURCE
CONFIG_INITRAMFS_SOURCE="/home/a/product/Hi3531_SDK_V1.0.8.0/rootfs"
 

配置编译BusyBox

BusyBox的配置程序和Linux内核菜单配置方式简直一模一样,十分方便易用。使用make menuconfig命令就可以进行配置

技术分享

配置过程主要有几点需要修改的:

因为我们要将BusyBox交叉编译成ARM可执行程序放在开发板上执行,所以需要使用交叉编译器arm-linux-gcc
来编译BusyBox。所以需要修改BusyBox根目录下的Makefile,找到
ARCH ?= $(SUBARCH)
CROSS-COMPILE ?=
修改成ARM的配置,如下:
ARM ?= arm
CROSS-COMPILE ?= arm-linux-

在BusyBox配置界面里修改几个配置:

Busybox Settings --->
Build Options
Build BusyBox as a static binary (no shared libs)
这个选项是一定要选择的,这样才能把BusyBox编译成静态链接的可执行文件,运行时才独立于其他函数库,
否则必须要其他库文件才能运行

Busybox Settings --->
Installation Options
Don’t use /usr
这个选项也是要选上的,否则make install 后BusyBox将安装在原系统的/usr下,这将覆盖系统原有的命令。
选择这个选项后,make install后会在BusyBox目录下生成一个叫_install的目录,里面有BusyBox和指向他
的链接。

Init Utilities --->
init
这个选项最好选上,这样BusyBox就可以初始化脚本inittab,可以用来初始化Linux系统。

如果要让BusyBox包含一个可以用于解释Linux命令的shell,需要配置BusyBox的Shells选项里的内容:

Shells --->
这里可选的shell有多种,包括ash,hush,lash,msh。最好使用ash,因为它是功能最全也最类似于一般
Linux系统中的BASH的。同时注意第一行的:
Choose your default shell (none) --->
这里需要回车进去选择默认的Shell,例如选择了ash后,第一行的内容就会变成:
Choose your default shell (ash) --->
这样BusyBox才会生成sh的链接并且将这个sh指向对应的shell(ash)。
其他选项都是一些Linux基本命令选项,可以根据自己的需要选择配置,第一次的话用默认的设置即可

编译

如果配置好了BusyBox,就可以使用make命令编译了。

#make

#make install

默认情况下,make install完成后会在BusyBox目录下创建一个新的本地子目录 _install,其中包含了基本的 Linux 环境。在这个目录中,会有一个链接到 BusyBox 的 linuxrc 程序。这个 linuxrc 程序在构建安装盘或急救盘(允许提前进行模块化的引导)时非常有用。同样在这个目录中,还有一个包含操作系统二进制文件的 /sbin 子目录。还有一个包含用户二进制文件的 /bin 目录。在构建软盘发行版或嵌入式初始 RAM 磁盘时,可以将这个 _install 目录迁移到目标环境的根目录中

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install# ls
bin  linuxrc  sbin  usr


4、制作完整的根文件系统

BusyBox虽然为我们创建了Linux根系统中最基本的shell和一些常用命令,但是一个根文件系统还不只包含这些,还需要其它的一些内容。

创建一个比较完整的根文件系统目录结构

本章第一节已经介绍了根文件系统中的一些目录,这些目录是Linux正常运行时所必需的。我们可以在BusyBox的_install基础上创建完整的根文件系统目录,一般步骤如下:

1 在PC上创建一个目标根文件系统的目录,例如/rootfs,将BusyBox里的_install目录里所有内容复制到这个文件夹里:cp –r _install /rootfs

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install#
 cp -r bin ../../../../rootfs
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install#
 cp -r sbin ../../../../rootfs
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install#
 cp -r usr ../../../../rootfs
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install#
 cp -d linuxrc ../../../../rootfs
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/osdrv/busybox/busybox-1.16.1/_install# 
ls -l ../../../../rootfs
total 12
drwxr-xr-x 2 root root 4096 May 26 01:28 bin
lrwxrwxrwx 1 root root   11 May 26 01:30 linuxrc -> bin/busybox
drwxr-xr-x 2 root root 4096 May 26 01:29 sbin
drwxr-xr-x 4 root root 4096 May 26 01:29 usr 
  语法: cp [选项] 源文件或目录 目标文件或目录

    说明:该命令把指定的源文件复制到目标文件或把多个源文件复制到目标目录中。

    该命令的各选项含义如下:

    - a 该选项通常在拷贝目录时使用。它保留链接、文件属性,并递归地拷贝目录,其作用等于dpR选项的组合。

    - d 拷贝时保留链接。

    - f 删除已经存在的目标文件而不提示。

    - i 和f选项相反,在覆盖目标文件之前将给出提示要求用户确认。回答y时目标文件将被覆盖,是交互式拷贝。

    - p 此时cp除复制源文件的内容外,还将把其修改时间和访问权限也复制到新文件中。

    - r 若给出的源文件是一目录文件,此时cp将递归复制该目录下所有的子目录和文件。此时目标文件必须为一个目录名。

    - l 不作拷贝,只是链接文件。

<p>复制指定目录下的全部文件到另一个目录中
假设复制源目录 为 dir1 ,目标目录为dir2。怎样才能将dir1下所有文件复制到dir2下了
如果dir2目录不存在,则可以直接使用
cp -r dir1 dir2
即可。
如果dir2目录已存在,则需要使用
cp -r dir1/. dir2
如果这时使用cp -r dir1 dir2,则也会将dir1目录复制到dir2中,明显不符合要求。</p>




2 在/rootfs下创建目录etc/,dev/,lib/,tmp/,usr/,var/目录,同时var/目录里还需要创建var/run和var/log等目录。

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir etc
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir dev
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir lib
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir tmp
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir usr
mkdir: cannot create directory ‘usr’: File exists
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# mkdir var
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# cd var
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/var# ls
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/var# mkdir run
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/var# mkdir log
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/var# cd ..
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# ls
bin  dev  etc  lib  linuxrc  sbin  tmp  usr  var

318 的rootfs

[[email protected] c300]# ls -R rootfs
rootfs:
bin  dev  etc  init  lib  linuxrc  mnt  proc  sbin  sys  tmp  usr  var

rootfs/bin:
[       basename  chmod  cp    dirname  env     fgrep   grep      id       killall5  logname  mkfifo  netstat  printenv  realpath  sh       telnet  top    umount  usleep
[[      busybox   chown  cut   dmesg    expand  free    hexdump   install  ln        ls       mknod   nice     ps        rm        sleep    test    touch  uname   vi
arping  cat       cksum  date  echo     expr    ftpget  hostid    kill     logger    mesg     mount   ping     pwd       rmdir     strings  tftp    true   uniq    who
ash     chgrp     cmp    df    egrep    false   ftpput  hostname  killall  login     mkdir    mv      ping6    readlink  setsid    tar      time    tty    uptime  yes

rootfs/dev:
console  null  ptmx  pts  ttyS0

rootfs/dev/pts:

rootfs/etc:
fstab  group  hostname  init.d  inittab  localtime  mtab  passwd  profile  resolv.conf  shadow  shells  sysctl.conf

rootfs/etc/init.d:
rcS  reboot

rootfs/lib:
ld-2.9.so      libc-2.9.so      libdl-2.9.so   libm-2.9.so    libnss_dns-2.9.so    libpthread-2.9.so  librt-2.9.so         libutil-2.9.so
ld-linux.so.2  libcrypt-2.9.so  libdl.so.2     libm.so.6      libnss_dns.so.2      libpthread.so.0    librt.so.1           libutil.so.1
libanl-2.9.so  libcrypt.so.1    libgcc_s.so    libnsl-2.9.so  libnss_files-2.9.so  libresolv-2.9.so   libthread_db-1.0.so  modules
libanl.so.1    libc.so.6        libgcc_s.so.1  libnsl.so.1    libnss_files.so.2    libresolv.so.2     libthread_db.so.1

rootfs/lib/modules:

rootfs/mnt:

rootfs/proc:

rootfs/sbin:
arp  chpasswd  getty  halt  hwclock  ifconfig  init  insmod  klogd  logread  lsmod  mdev  poweroff  reboot  rmmod  route  sysctl  syslogd  telnetd  udhcpc

rootfs/sys:

rootfs/tmp:

rootfs/usr:
bin  lib  local  sbin  share

rootfs/usr/bin:
msp-control

rootfs/usr/lib:
libmsp.so  libmsp.so.0  libmsp.so.0.1.0

rootfs/usr/local:

rootfs/usr/sbin:
init  reboot

rootfs/usr/share:
udhcpc

rootfs/usr/share/udhcpc:
default.script

rootfs/var:
[[email protected] c300]# 
[[email protected] rootfs]# cd dev
[[email protected] dev]# ls
console  null  ptmx  pts  ttyS0
[[email protected] dev]# ls -l
鎬昏 24
crwxr-xr-x 1 root root 5,  1 2015-10-26 console
crw-r--r-- 1 root root 1,  3 2015-10-26 null
crw-r--r-- 1 root root 5,  2 2015-10-26 ptmx
drwxr-xr-x 2 root root  4096 2015-10-26 pts
crwxr-xr-x 1 root root 4, 64 2015-10-26 ttyS0
mknod 的标准形式为:       mknod DEVNAME {b | c}  MAJOR  MINOR

       1,DEVNAME是要创建的设备文件名,如果想将设备文件放在一个特定的文件夹下,就需要先用mkdir在dev目录下新建一个目录;

       2, b和c 分别表示块设备和字符设备:

                  b表示系统从块设备中读取数据的时候,直接从内存的buffer中读取数据,而不经过磁盘;

                  c表示字符设备文件与设备传送数据的时候是以字符的形式传送,一次传送一个字符,比如打印机、终端都是以字符的形式传送数据;

       3,MAJOR和MINOR分别表示主设备号和次设备号:

             为了管理设备,系统为每个设备分配一个编号,一个设备号由主设备号和次设备号组成。主设备号标示某一种类的设备,次设备号用来区分同一类型的设备。linux操作系统中为设备文件编号分配了32位无符号整数,其中前12位是主设备号,后20位为次设备号,所以在向系统申请设备文件时主设备号不好超过4095,次设备号不好超过2^20 -1。

 .

 下面,我们就可以用mknod命令来申请设备文件了。      

          mkdir -p  /dev/cobing

           mknod /dev/cobing/mydev1 c 128 512

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# mknod  console c 5 [email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# mknod  null c 1 3
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# mknod ptmx c 5  2 
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# mknod  ttyS0 c 4  64 [email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# mkdir pts
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# ls
console  null  ptmx  pts  ttyS0
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs/dev# ls -l
total 4
crw-r--r-- 1 root root 5,  1 May 26 03:04 console
crw-r--r-- 1 root root 1,  3 May 26 03:04 null
crw-r--r-- 1 root root 5,  2 May 26 03:06 ptmx
drwxr-xr-x 2 root root  4096 May 26 03:07 pts
crw-r--r-- 1 root root 4, 64 May 26 03:07 ttyS0
318 rootfs的init
[[email protected] rootfs]# cat init
#!/bin/busybox ash
# Copyright (C) 2006 OpenWrt.org

/bin/busybox mount -t sysfs sysfs /sys
/bin/busybox mount -t proc  proc  /proc

exec /sbin/init "[email protected]" </dev/console >/dev/console 2>&1
拷贝过来

[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# gedit init
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# chmod 777 init
[email protected]:~/product/Hi3531_SDK_V1.0.8.0/rootfs# 

3 生成etc/里的设备文件,例如tty,console,fb(FrameBuffer),mtdblock(Memory Technology Device)等,这些设备文件是Linux很多驱动程序及就用程序正常的工作的基础。这些设备文件都是与相应的硬件相联系的,主要包含几种信息:设备类型,主设备号,次设备号。

其中设备类型主要包括字符设备(Character Device)和块设备(Block Device),字符设备主要字符的输入输出设备如键盘、鼠标等,块设备主要指整块数据的输入输出设备,如FLASH、硬盘等存储设备,一般包含缓冲区机制。

主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3,而次设备对应到每个具体的设备上,一般在/proc/devices文件里可以找到相关信息。

对于一个已存在的设备文件可以通过ls –l 命令来获取它的设备相关信息。

ls  –l  /dev/console

crw-rw---- 1 root root 5,1 Apr 14 23:08 /dev/console

可以看出第一个字母为c,这代表/dev/console是字符设备,若第一个字母为b,则为块设备。而root之后的 5,1就分别为相应设备的主次设备号了。

这里需要强调一点,设备文件类似于配置文件,存储的是一些设备信息,里面不包含特定平台下的指令,所以设备文件本身是平台无关的,也就是说在I386上创建的设备文件可以放在ARM的根文件系统,而可以被Linux正确识别的。

基本了解设备后,还需要如何创建它们,一般情况下可以使用mknod生成相应设备文件。mknod是Linux中用来创建设备文件的命令,格式如下:

mknode [–m MODE] NAME TYPE [MAJOR MINOR]

其中MODE用于指定设备文件的访问权限。NAME为设备文件的文件名,TYPE为相应的设备类型(字符设备c,块设备b等),MAJOR和MINOR分别为主次设备号。

例如要创建刚才的那个console命令可用如下的命令:

mknode –m 660 console c 5 1

设备文件的创建除了使用mknod命令,还可以使用MAKEDEV命令,MAKEDEV可以较方便的创建一系统的设备文件,一般的Linux发行版都有自带,其基本格式如下:

MAKEDEV –d directory -m maxdevices device

其中directory为设备文件的目标存放文件夹,若不指定则为当前系统下的/dev里。maxdevices为最大的设备数,因为MAKEDEV一般会创建一种设备的一系列设备文件,一般从0开始编号,直到maxdevices,所以一般这个需要指定,要不会生成较多的相关设备文件,而一般我们是不需要这么多的。最后一个参数device为对应的设备文件名,包括tty,vt,mem,null,zero,fd,hd,audio,sound等。这些参数的详细内容以及更多的参数选项,可以参考man手册。

可以这样创建硬盘的设备文件hd

MAKEDEV –d /rootfs/dev -m 2 hda

这条命令就会在/rootfs/dev目录中创建hda和hda1两个设备文件,指向第一块硬盘和第一块硬盘的第一个分区。

对于目标根文件系统中的设备文件,一般都应放在etc/目录中,可以用如下几种方法来获取相应的设备文件:

ü 可以手动用mknod命令一个个的创建设备文件;

ü 可以使用MAKEDEV来创建设备文件;

ü 甚至可以直接拷贝PC系统中部分设备文件至目标根文件系统中。

2 构建lib/目录。

lib/目录放的是Linux就用程序所需的库文件,其实也是目标平台的指令代码,所以这里的文件与etc/里不一样,必须与相应的硬件平台相对应,例如i386里的库文件放到ARM系统中就不能使用的,这点与Linux的可执行文件一样。在PC机上使用ls /lib命令就可以看到很多.so结尾的库文件,这些.so文件就是Linux的动态链接库(类似于Windows下的DLL文件)。要注意的是.so文件名后缀还可能加上一些版本号标志例如.so.1,.so.1.2等都是动态链接库。

ü 目标根文件系统中的库文件从哪里来?

一般这些库都是事先编译好的,而且跟编译器相关的(glibc等),例如我们使用arm-linux-gcc进行编译则需要相应版本的一些库文件,这些库文件可以从编译器所在的目录里直接拷贝。对于ELDK开发包,可以从ELDK目录下的arm/lib/目录里复制相应文件。

ü 目标根文件系统需要哪些基本库文件?

库文件实际上是由其它可执行文件来调用的,所以库文件的取舍是由根文件系统中所包含的可执行文件来决定的。但是要运行可执行文件,一般有几个是系统必须的。它们是ld(ld-linux),libc,几乎所有的可执行文件都需要调用到这两个库文件。

ld(ld-linux):ld-linux.so 实际上就是一个可执行程序。这是负责执行动态装载的代码。它从可执行程序读取头信息(ELF格式的),然后通过这些信息判断必要的库和需要装载的库。之后,执行动态链接,修改可执行程序和装载的库中的所有地址指针,使程序能够运行。一般的文件名可能为ld-2.3.2.so,ld-linux.so.2,这点与编译器和系统版本有关。

libc:libc.so.6 是以 ld-linux.so.2 为基础架构而完成的动态链接库,它几乎负责了所有常用的标准 C 函数库,例如 Linux 下写的 Socket 程序,其中的connect()、bind()、send() .....之类的函数,都是由 libc.so.6 所提供的。

所以一个最基本的lib/目录应该至少包含这ld-linux.so.2和libc.so.6这两个文件。

ü 应用程序需要哪些库文件?

前面已经说过动态链接库是由应用程序(可执行文件)调用的,那对于一个特定的可执行文件是如何判断它需要哪些库文件的?一般可以编译器的ldd命令来查看,例如arm-linux-gcc包含了arm-linux-ldd命令用来查看ARM可执行文件调用的动态链接库。arm-linux-ldd的功能就是列出可执行文件及动态链接库运行时需要的库文件,例如,对于刚才所指的libc.so.6可以查找出其需要的动态链接库。这里我们假设为ELDK里的libc。

# file /eldk/arm/libc.so.6

libc.so.6:symbolic link to `libc-2.3.5.so`

通过file命令看出这里的libc.so.6实际上是个符号连接,链接到libc-2.3.5.so,所以我们继续追查libc-2.3.5.so:

#file libc-2.3.5.so

libc-2.3.5.so: ELF 32-bit LSB shared object, ARM, version 1(ARM), stripped

从这里可以明显的看出这个是ARM的Shared Object,也就是ARM格式的动态链接库。到这里可以判断出libc.so.6是ARM指令的。下来看libc.so.6到底需要哪些库文件:

#arm-linux-ldd libc.so.6

ld-linux.so.2 => not found

可以看出libc.so.6库文件需要ld-linux.so.2这个动态链接库(not found 说明在当前系统中未找到相应的库,因为系统是i386而需要的是ARM格式,所以找不到)。

这样通过arm-linux-ldd命令就可以确定各个程序所需的动态链接库,然后根据需要放到lib/目录里,就组成目标根文件系统的动态链接库集合了。

3若选择了BusyBox的init模块,则需要配置BusyBox的初始化文件。

因为Linux系统加载根文件系统后需要执行一些配置以初始化整个Linux的工作环境及init程序和Shell等。这个文件就是etc/inittab。关于此文件的详细内容可以查看man inittab。但是BusyBox的inittab格式与一般Linux下的inittab的格式是不同,所以直接拷贝PC机上/etc/inittab文件到BusyBox制作的根文件系统中是不能用的,那怎么办呢?

BusyBox自带了符合它的格式的inittab样本文件,放在examples目录下,主要内容包括:

::sysinit:/etc/init.d/rcS

::askfirst:-/bin/sh

tty2::askfirst:-bin/sh

tty3::askfirst:-bin/sh

tty4::askfirst:-bin/sh

#Stuff to do when restarting the init process

::restart:/sbin/reboot

#Stuff to do before rebooting

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount -a -r

::shutdown:/sbin/swapoff –a

BusyBox的inittab的每一行格式如下:

<id>:<runlevels>:<action>:<process>

总共包含四项,每项间以”:”隔开。

第一二项<id>和<runlevels>在BusyBox都是忽略掉的,所以可以看到BusyBox提供的inittab样本文件的所有项目都是以两个冒号”::”开头的。

第三项<action>为动作描述,可选项为sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel 和 shutdown。其中大部分动作可以通过动作名直接理解它的作用。其中askfirst会在登录shell前提示用户,而respawn则不会提示。

第四项<process>指定了<action>动作应执行的脚本文件。

知道了格式,下面简单的分析一下inittab样本文件:

第一行::sysinit:/etc/init/rcS实际上指定了系统初始化(sysinit)时脚本为/etc/init/rcS,这个可以根据自己的需要更改的。

但是对于不同的终端设备的不同配置区别在于开头的标志,例如对于tty2终端,则有对应的操作 tty2::askfirst:-bin/sh。此行的意思指对于tty2使用shell为/bin/sh,同时对askfirst(有提示信息再要求登陆)。 若对于某个特定的终端设备可以直接将前面的设备标志去掉,例如ttyS0, ttyS1等。

第二行::askfirst:-/bin/sh指定了系统第一个终端在加载shell为/bin/sh,而且在进入shell前会提示用户。其它行请读者自行分析。

4在etc/目录里除了inittab文件外,还需要其它的一些基本的文件

例如fstab、passwd、group、inputrc等,由于篇幅所限,不可能一一详解,读者可以参考其它书籍或者man手册,对于一些文件读者也可借用别的嵌入式根文件系统里的内容,然后在此基础上进行修改以符合自己的系统。这里简单介绍etc/里的几个文件:

ü fstab:这个文件描述系统中各种文件系统的信息。在这个文件中,每个文件系统用一行来描述,在每一行中,用空格或TAB符号来分隔各个字段,文件中以*开头的行是注释信息。一般内容可能如下:

/dev/mtdblock2 / jffs2 defaults 0 0

none /tmp ramfs defaults 0 0

none /proc proc defaults 0 0

第一列(字段):设备名或者设备卷标名(一般为/dev里的对应的设备文件)

第二列(字段):设备挂载目录 (例如上面的“/”或者“/tmp”)

第三列(字段):设备文件系统 (例如上面的“ext3”或者“vfat”)

第四列(字段):挂载参数 (具体可以查看帮助man mount)

对于已经挂载好的设备,例如上面的/dev/sda2,现在要改变挂载参数,这时可以不用卸载该设备,而可以使用下面的命令(没有挂载的设备,remount 这个参数无效)

#mount /mnt -o remount,ro (改defaults为ro)

关于其它参数请参考man手册。

第五列(字段):指明是否要备份。(0为不备份,1为要备份)

第六列(字段):指明自检顺序。 (0为不自检,1或者2为要自检,如果是根分区要设为1,其他分区只能是2)

ü passwd和group保存着Linux系统的用户组和用户名等,与硬件平台无关,为方便起见,可以从现有的Linux系统中拷贝过去即可。

etc/目录里的配置文件较多,不可能一一解释,请读者在创建时多参考已有的系统。

5、总结

上面已经介绍一个根文件系统的创建过程,如果完整的按照上面的步骤做下来,应该就会在/rootfs下得到了一个相对完整的根文件系统,这个根文件系统主要BusyBox的bin/、sbin/目录,etc/系统配置文件目录以及lib/动态链接库所在目录等,这样一个Linux应用程序可执行的最小环境基本已经搭成了。之后可以在这个根文件系统中添加所需的应用程序等等。

但是这个根文件系统又是怎么放到目标开发板里的呢?

通常的做法是将整个根文件系统打包成某种文件系统格式的映像,然后下载到目标开发板的存储设备里(如FLASH等)。

用什么程序可以打包?支持几种格式呢?

通常使用mkfs系统命令。mkfs命令可以生成指定文件系统类型的映像文件。对于不同的文件系统类型需要不同的mkfs命令,例如EXT2,EXT3类型的文件可以使用mkfs.ext2和mkfs.ext3等。而通常嵌入式开发板使用FLASH作为存储设备,所以对应的文件系统类型一般为JFFS2,所以使用命令mkfs.jffs2命令,这个命令一般在开发板提供的工具有,也可以从网上搜索下载,这个命令一般是运行在PC系统上的,所以一般为I386可执行文件。

mkfs.jffs2的基本命令格式如下:

mkfs.jffs2 -r DIR -o FILE -e SIZE --pad=PADSIZE

其中DIR为要打包的文件夹,FILE为输出的文件路径,SIZE为每次擦除的块大小(默认为64KB)。PADSIZE为填充大小,这个参数强制使目标文件大小至少为PADSIZE字节,若实际数据没有这么大,则使用0xFF填充,这个参数很重要,在将映像写入目标开发板时一般应与实际根文件系统大小相符(类似于总磁盘容量),这样具有初始化的作用,若不相符合,在挂载这个JFFS2根文件系统时可能会出现一些问题。

下面给个简单的例子,这个例子将/rootfs的这个根文件系统打包成文件rootfs.img,且总大小为1M(0x100000字节)。

mkfs.jffs2 -r /rootfs -o rootfs.img -e 0x40000 --pad=0x100000

做好映像文件后就可以将这个映像文件写入目标板中,通常使用U-BOOT等BootLoader通过网卡下载到开发板内存中,然后再写入开发板的FLASH里。在U-BOOT里若网卡驱动可用,通常用tftp下载,再使用相关的FLASH操作命令写数据。









318镜像的制作

#!/bin/sh

mkfs.jffs2 --pad=2228224 -e 64KiB -d app -o app.img
cp app.img /tftpboot -f
cp app.img ../src -f

msp=../src/Default_EA_10_25_03_04-m823.axf
kernel=../src/zImage
uboot=../src/u-boot.bin

PACKET=c318.bin

dd if=$uboot of=uboot.out conv=sync ibs=384k count=1
dd if=$msp of=msp.out conv=sync ibs=2560k count=1
dd if=$kernel of=kernel.out conv=sync ibs=3072k count=1

cat uboot.out > $PACKET
cat msp.out >> $PACKET
cat kernel.out >> $PACKET
cat app.img >> $PACKET

cp $PACKET ../src/ -f
rm -f uboot.out msp.out kernel.out

a8分区制作

[email protected]:image# cat build_fs
mkfs.ubifs -r $1 -m 2048 -e 126KiB -c $3 -o ubifs.img
ubinize -o $4 -m 2048 -p 128KiB -O 512 $2
rm -f ubifs.img

[email protected]:image# cat makeall
./build_fs ./app app.cfg 760 app.img
./build_fs ./dummy data.cfg 760 data.img
./build_fs ./dummy log.cfg 360 log.img

[email protected]:image# ls
app      app.img   build_lib  data.img  log.cfg  makeall  ubinize.cfg
app.cfg  build_fs  data.cfg   dummy     log.img  ubi.img

[email protected]:image# cat app.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=95MiB
vol_type=dynamic
vol_name=apps
vol_flags=autoresize

[email protected]:image# cat log.cfg
[ubifs]
mode=ubi
vol_id=0
vol_size=40MiB
vol_type=dynamic
vol_name=logs
vol_flags=autoresize

[email protected]:image# cat data.cfg
[ubifs]
mode=ubi
vol_id=0
vol_size=95MiB
vol_type=dynamic
vol_name=data
vol_flags=autoresize

[email protected]:image# cat ubinize.cfg 
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=35MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

do_copy()
{
    if [ -e "$1/lib/$2" ]; then
        cp $1/lib/$2 .
        ln -s $2 $3
    fi
}

do_copy $1 ld-2.8.so ld-linux.so.3
do_copy $1 libanl-2.8.so libanl.so.1
do_copy $1 libc-2.8.so libc.so.6
do_copy $1 libcidn-2.8.so libcidn.so.1
do_copy $1 libcrypt-2.8.so libcrypt.so.1
do_copy $1 libdl-2.8.so libdl.so.2
do_copy $1 libgcc_s.so.1 libgcc_s.so
do_copy $1 libm-2.8.so libm.so.6
do_copy $1 libnsl-2.8.so libnsl.so.1
do_copy $1 libnss_compat-2.8.so libnss_compat.so.2
do_copy $1 libnss_dns-2.8.so libnss_dns.so.2
do_copy $1 libnss_files-2.8.so libnss_files.so.2
do_copy $1 libnss_hesiod-2.8.so libnss_hesiod.so.2
do_copy $1 libnss_nis-2.8.so libnss_nis.so.2
do_copy $1 libnss_nisplus-2.8.so libnss_nisplus.so.2
do_copy $1 libpthread-2.8.so libpthread.so.0
do_copy $1 libresolv-2.8.so libresolv.so.2
do_copy $1 librt-2.8.so librt.so.1
do_copy $1 libthread_db-1.0.so libthread_db.so.1
do_copy $1 libutil-2.8.so libutil.so.1

if [ -e "$1/usr/lib/libstdc++.so.6.0.10" ] ; then


















































以上是关于Hi3531 软件环境搭建的主要内容,如果未能解决你的问题,请参考以下文章

hi3531 SDK 编译 uboot, 改动PHY地址, 改动 uboot 參数 .

Hi3516开发笔记:Hi3516虚拟机交叉开发环境搭建之配置QtCreator开发交叉编译环境

HI3518E平台ISP调试环境搭建

Hi3516开发笔记:在QtCreator开发环境中引入海思sdk的bsp包,运行显示Qt界面

海思Hi3516DV300之Ubuntu20.04环境搭建和编译

海思Hi3516DV300之Ubuntu20.04环境搭建和编译