天天看点

在BeagleBone Black上构建Linux 0.1

我构建的目标平台为BeagleBone Black,

'http://beagleboard.org/'。

 交叉编译工具为Sourcery CodeBench Lite,

'http://www.mentor.com/'。

 要构建Linux,很简单,只有3个部分,

1,bootloader,即启动引导程序,我选择U-Boot。

2,Linux内核。

3,应用程序。

 我还没研究是什么决定了32位和64位。

 我主要的资料,

Running Linux

介绍Linux的书,这才叫入门级,了解下Linux的思想即可,书的内容可能有些过时,

 这本书不是介绍怎么使用Linux的。如果想知道怎么使用Linux,

 可看看Linux Pocket Guide,很薄。

 鸟哥的书也不错,感觉挺详细的,好于大部分书,我没看。

 我连shell脚本都不会写呢,很多命令没用过,这与构建Linux关系不大。

Building Embedded Linux Systems

教构建嵌入式Linux的,了解下思想即可。

http://www.linuxfromscratch.org/

教构建各种Linux的网站,最关键的是网站给出了Linux由哪些应用程序构成。

 我没有用网站中的方式,sed那种命令不会。也是了解下思想即可。

If you can’t explain it simply, you don’t understand it well enough.

                                                    --Albert Einstein

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

 BeagleBone Black有4种启动方式,我选择用SD卡。

 准备SD卡,将SD卡插到电脑中,在我的系统中被识别为/dev/sdb。

  分区:

# fdisk /dev/sdb

用法很简单,输入'm',就可得到帮助。

 第一个分区64M,类型为FAT32 (LBA),加上启动标记。

 第二个分区为余下的全部,类型默认为Linux,不必改。

 参考过程是这样的,

 输入'o',新建一个空DOS分区表,这会清除所有分区。

 输入'p',会列出分区列表,此时应该没有。

 输入'n'来添加新分区,直接'enter',接受默认为主分区,'enter'接受默认为第一分区,

'enter'接受默认的开始扇区,输入'+64M',设置分区大小为64M。

 输入't',来改变分区类型,自动选择了第一个分区,输入l可列出所有分区列表的代码,

 输入'c'选择W95 FAT32(LBA)。

 输入'a',在第一分区设置可启动标记。

 输入'n','enter'主分区,'enter'第二个,'enter'起始扇区,'enter'结束扇区。

 输入'w',将改动写入分区表。

 格式化:

# mkfs.vfat -F 32 /dev/sdb1

 # mkfs.ext4 /dev/sdb2

第一个分区用来放U-Boot,板子启动后就会找一个叫MLO的文件,编译U-Boot后,就会生成

 一个MLO,不必担心。

 第二个分区用来放Linux系统。

sdb2被格式化后,里面自动有个lost+found,文件系统的结构中正好有一条:

/lost+found: Filesystem-specific recoverable data

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

我的文件系统目录结构

/

 /bin             --> /usr/bin/

 /boot/

 /dev/

 /etc/

 /home/

 /home/root

 /lib             --> /usr/lib/

 /mnt/

 /proc/

 /run/

 /sbin            --> /usr/bin/

 /sys/

 /tmp

 /usr/

 /usr/app/

 /usr/bin/

 /usr/include/

 /usr/lib/

 /usr/sbin       --> bin/

 /usr/share/

 /usr/share/man/

 /var/

 /var/run         --> /run/

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

编译时的一些配置等,我为了方便调用,放到这里,不要看。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools

 $ export CROSS_COMPILE=arm-none-linux-gnueabi-

 # chown -R 0:0 

 # chgrp -v tty /usr/app/util-linux/bin/wall

 # chown -R spy:users 

找readelf结果中带"Shared library"的行

readelf -ld | grep "Shared library"

以可读写重新挂载根文件系统

mount -n -o remount,rw /

放到交叉编译器搜索库中的程序库

libcap,pam,ncurses,gdbm,db,iptables

 coreutils与util-linux重复的命令。

kill

 shadow与util-linux重复的命令。

{login,nologin,su}

 shadow与coreutils重复的命令。

groups

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

下面是编译软件的过程

U-Boot

============ http://www.denx.de/wiki/U-Boot/WebHome

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ export CROSS_COMPILE=arm-none-linux-gnueabi-

 $ make O=../u-boot distclean

 $ make O=../u-boot am335x_boneblack_config

 $ make O=../u-boot all

 --------------------------------------------------------------------------------

源码中正好有am335x_boneblack这个配置文件,对应我的开发板,想知道可用的配置文件

 看README吧,它会告诉你到另一个文件中找。

 忘了是编译U-Boot还是Linux内核的时候,提示我的系统中缺少bc,用你的包管理器安上就好了。

编译完后,现在就可以找找成就感了,

 将MLO和u-boot.img复制到SD卡的第一个分区里;

 将串口调试用的线与计算机相连,启动串口调试程序,如Putty。

 将SD卡插入开发板,保持按下板子上的启动选择键,插上电源,板子会从SD卡启动,

 可以松开启动选择键了。

Putty的窗口上会打印一些信息,你会看到一个1秒的倒计时,然后U-Boot会运行环境变量中

 已经设置好的一些列命令,比如将Linux内核载入内存,但此时还没有内核文件,U-Boot会

 停留在它自己的命令行中,你可以输入命令,如reset,这会让板子重启,倒计时的时候

 按下计算机上的任意键,U-Boot就不会运行环境变量中的命令了,可玩一玩下面的演示。

 给出U-Boot中的一些演示,输入help可显示所有命令。

help后接命令,可显示该命令的帮助。如"help help"。

U-Boot# mmc rescan

 U-Boot# mmc list

 OMAP SD/MMC: 0

  OMAP SD/MMC: 1

 U-Boot# mmc dev

 mmc0 is current device

 U-Boot# mmc part

 Partition Map for MMC device 0  --   Partition Type: DOS

 Part    Start Sector    Num Sectors     UUID            Type

   1     2048            131072          29942d7e-01     0c Boot

   2     133120          15390720        29942d7e-02     83

 U-Boot# ls mmc 0:1

    100688   mlo

    308232   u-boot.img

       510   uenv.txt

 3 file(s), 0 dir(s)

 U-Boot# ls mmc 0:2

 <DIR>       4096 .

 <DIR>       4096 ..

 <SYM>          7 bin

 <DIR>       4096 boot

 <DIR>       4096 dev

 <DIR>       4096 etc

 <DIR>       4096 home

 <SYM>          7 lib

 <DIR>       4096 lost+found

 <DIR>       4096 mnt

 <DIR>       4096 proc

 <DIR>       4096 run

 <SYM>          7 sbin

 <DIR>       4096 sys

 <DIR>       4096 tmp

 <DIR>       4096 usr

 <DIR>       4096 var

 U-Boot# mmcinfo

 Device: OMAP SD/MMC

 Manufacturer ID: 3

 OEM: 5344

 Name: SU08G

 Tran Speed: 50000000

 Rd Block Len: 512

 SD version 3.0

 High Capacity: Yes

 Capacity: 7.4 GiB

 Bus Width: 4-bit

 U-Boot# mmc dev 1

 mmc1(part 0) is current device

 U-Boot# mmcinfo

 Device: OMAP SD/MMC

 Manufacturer ID: fe

 OEM: 14e

 Name: MMC02

 Tran Speed: 52000000

 Rd Block Len: 512

 MMC version 4.41

 High Capacity: No

 Capacity: 1.8 GiB

 Bus Width: 4-bit

 U-Boot# mmc dev 0

 mmc0 is current device

 U-Boot#

 fatls,ext4ls也可以显示文件,但对应某种文件系统。

Linux

============ http://www.kernel.org/

内核配置文件我在'https://github.com/beagleboard/kernel/tree/3.13/configs'找的,

 复制一份名字改'.config'放到O指定的目录中。

 这样就可以用'make oldconfig'了。

 我的内核版本是Linux-3.13.5,并没有提示新的配置。

 如果要修改的话,要注意systemd对内核的配置是有要求的,我并没有改。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ export PATH=$PATH:/home/spy/Work/U-Boot/u-boot/tools

 $ export CROSS_COMPILE=arm-none-linux-gnueabi-

 $ make O=../linux ARCH=arm help

 $ make O=../linux ARCH=arm mrproper

 $ make O=../linux ARCH=arm oldconfig

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 uImage

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 dtbs

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 modules

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_MOD_PATH=/home/spy/Work/root modules_install

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_FW_PATH=/home/spy/Work/fw firmware_install

 $ make O=../linux ARCH=arm LOADADDR=0x80008000 INSTALL_HDR_PATH=/home/spy/Work/root/hdr headers_install

 --------------------------------------------------------------------------------

 'make help'是否指定ARCH,输出内容是不同的。

uImage就是压缩后的Linux内核,编译时需要mkimage这个工具,编译U-Boot的时候会生成那个工具,

 所以我编译内核之前指定了该工具的目录。

-dts  --> device tree source

 -dtb  --> device tree blob

 -dtbo --> device tree blob overlay

 -dtc  --> device tree compile

没研究为什么编译设备树是dtbs,是在make help的帮助中看到的。

 内核的配置中指定了很多把驱动编译成模块的,这部分需要'make modules'来单独编译。

 我构建完的系统并没有用到这些modules,插个U盘是可用的。

 编译完成后,可在输出文件夹的'arch/arm/boot'找到zImage, uImage和dts子文件夹,

dts里面有am335x-boneblack.dtb。zImage也是内核,也可以用,但我用的uImage。

 最后那三个安装目录自己选个更好的吧。

modules会安在'lib/modules'和'lib/firmware'2个文件夹中。

firmware也安在'lib/firmware'中,但与modules中的不同。我目前不知道firmware是干什么的。

headers还是需要安装的,它就像glibc那样,编译程序时被调用。

--------------------------------------------------------------------------------

下面可以验证了。

 将uImage文件,dts文件夹复制到SD卡第二个分区的/boot/里。

 其实dts中应该只需am335x-boneblack.dtb。

 启动开发板前应该了解下U-Boot如何载入Linux。

提示:我的研究在后面。现在可不必研究直接看我的处理。

 编译后的U-Boot是不能引导uImage的,通过printenv看U-Boot的环境变量,可看到

 它找的是zImage,而且am335x-boneblack.dtb是在/boot/中找,不是/boot/dts/。

 如果将zImage和am335x-boneblack.dtb放到/boot中应该能引导。

 为了符合我的要求,要修改环境变量,可以用editenv修改环境变量后saveenv。

 但还是别这么做了,我不知道它把环境变量保存到哪里去了。我以为把MLO和u-boot.img换回

 原始的可以恢复默认的环境变量值,但不是这样,把SD卡格式化后也没用。

 有可能是存到eMMC中了,我想尽各种办法破坏eMMC的数据,用了

'dd if=/dev/zero of=/dev/mmcblk1'也不行。

 除了mmcblk1还有个mmcblk1boot,可能是存到那里了,记着那个设备比较奇怪,没有验证。

 最后用'env default -a'然后'saveenv'恢复默认了。

 另一个方法是创建一个uEnv.txt文件,将它和MLO放到一起,内容如下。

 该文件中的环境变量会覆盖掉默认的环境变量。

一共6行,最后一行空白。

 改动不是很大,bootfile修改了内核名字,

loadfdt中只是在目录中加了“dts/”,

mmcloados主要是把bootz改成bootm。

mmcroot把只读改成了读写,原因是systemd启动后会创建一个machine-id到/etc中。

 也许有其他办法,如/etc/fstab文件,但我为了简单没创建那个文件。

mmcargs只是在后面指定了init为systemd,也有其他方法,如init为指向systemd的软链接。

 启动BeagleBone Black,待内核启动后会打印很多信息,最后你将目睹“kernel panic”,

 这是因为我们目前并没有init程序,为了找到成就感,你可以编译下面

 静态链接的“Hello world!”,放到某个目录中,然后在U-Boot的mmcargs变量中

 把init指定为那个hello。

hello.c

 $ arm-none-linux-gnueabi-gcc -o hello -static hello.c

再次启动,最后你看到的将是"Hello world!"。

下面就是应用程序了,可根据我的提示自行安排顺序,我曾经的顺序不是这样的。

 主要的过程就是glibc,bash,coreutils,util-linux,systemd,shadow,

这些中间的都是被依赖的程序。

bash需要libgcc_s.so.1,它位于gcc中,但编译gcc时间较长,gcc还依赖5个程序。

 迫不及待验证编译结果的话可以先把交叉编译器中的库复制到开发板系统中,

 我当初就那么做的。

glibc是程序库了,几乎动态链接的程序都要用到了,"Hello world"中的printf函数都需要。

bash是个shell,提供了人与计算机交互的界面。

coreutils里有很多常用命令,如'ls'。

util-linux也是有很多命令,如mount,login,fdisk。

systemd是个init程序。

shadow是和登陆相关的,主要是把'/etc/passwd'文件里的密码变成“x”,

 里面有login,passwd,useradd等命令。

 其实系统系统后的第一个程序是systemd,但它的文档较少,不了解是怎么工作的,

 所以先保证其他的能工作,再研究。

 至于怎么编译,源码中会有README,INSTALL等文档。

 需要注意的是我构建的系统与大多数Linux不同,我把所有程序都安装在了

/usr/app/{程序}/中。这是我改进Linux的开始,咱有大计划呀!

 我的想法如下,

 对于程序库,依旧在/usr/lib/中搜索,里面除了子文件夹都是软链接,指向app中

 相应的程序库。

 对于/usr/bin/中的程序,也是软链接。

 对于/etc/中的配置文件,其实有些程序不在那个目录找配置文件了,如果还在那个目录找,

 那么里面不是软链接,就是传统的配置文件。

glibc

============ [/usr/local] http://www.gnu.org/software/libc/

 > 

 < bash,            //这2个依赖和被依赖的,仅供参考,肯定不全的,下面也一样。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/glibc/glibc-build

 $ ../glibc-2.19/configure --prefix=/usr/app/glibc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi

 $ make

 $ make install install_root=/home/spy/Work/sources/glibc/glibc

 --------------------------------------------------------------------------------

源码中并没有makefile文件,这需要运行configure来生成。

 通过“configure --help”查看可用的选项。

prefix为安装目录;

build和host用来指定系统类型。可看看autoconf的手册中“Specifying target triplets”。

我们编译程序是用在其他的系统中,如果不指定install_root,它就要往prefix指定的目录安了,

 不要这样,我的路径还好,如果是/usr/lib/,那就破坏了你正使用的系统,不过我用的是普通用户,

 应该没权限往那个目录安。

 有了install_root,就会安装到/home/spy/Work/sources/glibc/glibc/usr/app/glibc,看看

makefile文件就会明白原理。

 那么把prefix指定为那个完整的目录,不使用install_root行不行呢。最好别这样。

 构建完glibc,其中的ld.so并不是在/lib/或/usr/lib/中找程序库,而是在glibc的库

 被安装到的目录中找,即'/usr/app/glibc/lib'。

 可见,这个prefix会记录到生成的程序中,所以最好别让目录那么长,那么乱。

 问题又来了,ld.so竟然不在/usr/lib/中找程序库,这可是传说中的默认目录啊。

 我的处理是在构建的系统中运行ldconfig,在bash中说。

gmp

============ [/usr/local] https://gmplib.org/

 > 

 < mpfr,mpc,isl,cloog,gcc

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/gmp/gmp-build

 $ ../gmp-5.1.3/configure --prefix=/usr/app/gmp --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/gmp/gmp

 --------------------------------------------------------------------------------

这个和下面的4个都是为gcc服务的。

 这里的安装目录用的是DESTDIR,看看源代码里的文档吧。

libtool: install: warning: remember to run `libtool --finish /usr/local/lib'

安装时遇到个警告,这个应该和ldconfig这个命令有关,应该是为了glibc的ld程序能找到这个库,我没执行这一步。

mpfr

============ [/usr/local] http://www.mpfr.org/

 > gmp,

 < mpc,gcc

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/mpfr/mpfr-build

 $ ../mpfr-3.1.2/configure --prefix=/usr/app/mpfr --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/mpfr/mpfr

 --------------------------------------------------------------------------------

修改lib/libmpfr.la,

# Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/gmp/lib/libgmp.la'

# Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'

也就是把目录改成完整的,这个过程的原因见mpc。

--------------------------------------------------------------------------------

libtool: install: warning: remember to run `libtool --finish /usr/local/lib'

警告依旧,不管他,怕他影响我正使用系统中的库。

 应该还会看到其他警告,如某个.la文件被moved,答案也是见mpc。

mpc

============ [/usr/local] http://www.multiprecision.org/

 > gmp,mpfr

 < gcc

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/mpc/mpc-build

 $ ../mpc-1.0.2/configure --prefix=/usr/app/mpc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-mpfr=/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/mpc/mpc

 --------------------------------------------------------------------------------

修改.la文件,

# Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib -L/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib /usr/app/mpfr/lib/libmpfr.la /usr/app/gmp/lib/libgmp.la -lm'

# Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib -L/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib /home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr/lib/libmpfr.la /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la -lm'

 --------------------------------------------------------------------------------

 libtool: install: warning: remember to run `libtool --finish /usr/local/lib'

isl

============ [/usr/local] http://freecode.com/projects/isl

 > gmp

 < gcc

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/isl/isl-build

 $ ../isl-0.12.2/configure --prefix=/usr/app/isl --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-gmp-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-gmp-exec-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/isl/isl

 --------------------------------------------------------------------------------

 # Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/gmp/lib/libgmp.la'

 # Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'

 --------------------------------------------------------------------------------

 libtool: warning: remember to run 'libtool --finish /usr/local/lib'

cloog

============ [/usr/local] http://www.bastoul.net/cloog/index.php

 > isl,gmp

 < gcc

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/cloog/cloog-build

 $ ../cloog-0.18.1/configure --prefix=/usr/app/cloog --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --with-isl=system --with-isl-prefix=/home/spy/Work/sources/isl/isl/usr/app/isl --with-isl-exec-prefix=/home/spy/Work/sources/isl/isl/usr/app/isl --with-gmp-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-gmp-exec-prefix=/home/spy/Work/sources/gmp/gmp/usr/app/gmp

修改Makefile libcloog-isl.la:

 libcloog_isl_la_LDFLAGS = -version-info 4:0:0 

     -L/home/spy/Work/sources/isl/isl/usr/local/lib 

 am_libcloog_isl_la_rpath = -rpath /home/spy/Work/sources/isl/isl/usr/app/isl/lib

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/cloog/cloog

 --------------------------------------------------------------------------------

 # Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/isl/isl/usr/app/isl/lib -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /usr/app/isl/lib/libisl.la /usr/app/gmp/lib/libgmp.la'

 # Libraries that this one depends upon.

 dependency_libs=' -L/home/spy/Work/sources/isl/isl/usr/app/isl/lib -L/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib /home/spy/Work/sources/isl/isl/usr/app/isl/lib/libisl.la /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib/libgmp.la'

 --------------------------------------------------------------------------------

--with-isl=system 目的是使用之前编译的isl,cloog源码中有也有份isl。

gcc

============ [/usr/local] http://gcc.gnu.org/

 > gmp,mpfr,mpc,isl,cloog

 < bash

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/gcc/gcc-build

 $ ../gcc-4.8.2/configure --prefix=/usr/app/gcc --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --target=arm-none-linux-gnueabi --enable-shared --enable-threads --enable-languages=c --with-gmp=/home/spy/Work/sources/gmp/gmp/usr/app/gmp --with-mpfr=/home/spy/Work/sources/mpfr/mpfr/usr/app/mpfr --with-mpc=/home/spy/Work/sources/mpc/mpc/usr/app/mpc --with-isl=/home/spy/Work/sources/isl/isl/usr/app/isl --with-cloog=/home/spy/Work/sources/cloog/cloog/usr/app/cloog

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/gcc/gcc

 --------------------------------------------------------------------------------

 gcc就是编译器了,我们编译软件就靠它了,gcc也包含一些库,我们的bash要用到。

gcc的配置选项太多了,我只额外用了

--enable-shared --enable-threads --enable-languages=c

也不知道是否需要。

 我编译了50分钟,现在是2014年,我这2手笔记本比较差了,

CPU 1.86GHz,内存2G的,DDR2的,单条1G。

bash

============ http://www.gnu.org/software/bash/

 > glibc,gcc

 < 

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/Bash/bash-build

 $ ../bash-4.3/configure --prefix=/usr/app/bash --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --without-bash-malloc --with-installed-readline

 $ make

 $ make DESTDIR=/home/spy/Work/sources/Bash/bash install

 --------------------------------------------------------------------------------

 --without-bash-malloc --with-installed-readline

对这2个不太了解,只是为了bash简单点。

 不知道readline干什么的,我构建的系统没有安readline。

--------------------------------------------------------------------------------

在这里推荐个工具,readelf,这是binutils中的一个命令。可查看二进制文件的信息,

 我用它主要是为了看到所依赖的库。

$ readelf -hld bin/bash

-a选项是打印所有的信息,我们用-hld就可以了。

 看看我们编译后的bash,它需要gcc中的libgcc_s.so.1,而我电脑中的bash却不需要那个库。

--------------------------------------------------------------------------------

有了shell,我们就可以在开发板中验证我们编译的结果了。

 至此,我们编译了glibc,gmp,mpfr,mpc,isl,cloog,gcc,bash。

 在复制到SD卡之前,我想应该先把mpfr,mpc,isl,cloog中的改动改回来。

 根据prefix,将编译后的程序复制到SD卡,/usr/lib/和/usr/bin/中添加相应的软链接。

 我并不是在这个时候才制作的软链接,每编译过一个程序,发现有bin和lib文件夹,

 就把软链接做好了,直接复制到SD卡中就可以了。

 至于怎么制作,我不擅长,写个脚本应该比较好,但我没学。

/etc/中不必有配置文件。

 在uEnv.txt中,把bootargs的init改为/usr/bin/bash。

 如果就这样启动的话,会提示找不到libgcc_s.so.1,因为这个库不在ld.so的搜索路径中。

 目前的搜索路径是/usr/app/glibc/lib。

 所以/usr/app/glibc/lib中有个libgcc_s.so.1就可以了,可以放一个软链接,就像/usr/lib中的。

 不要担心,这只是临时的。

 接下来我们要在开发板中运行ldconfig,这是glibc的一部分,它会读取ld.so.conf文件中的

 路径,然后建立一个ld.so.cache文件,这样ld.so就能利用ld.so.cache找到那些路径中的库了。

ld.so.conf文件不存在,而我们构建的系统还没有文本编辑器,所以要在启动之前建立该文件。

 内容就是

/usr/lib

很多文本文件都以空行结尾,我们也这么做吧。

 那么这个文件要放到哪里呢,一般是/etc/中,但在我们构建的系统中,ldconfig是到

/usr/app/glibc/etc/中找,所以要放到这个目录中。

 好,可以启动开发板了,进到shell之后,运行ldconfig。

 把/usr/app/glibc/lib中的libgcc_s.so.1删掉,重启,看看是不是可以正常运行了?

 这样的方法并不好,应该让编译glibc的时候可以指定ld.so的搜索路径。

 其实我当初用了更不好的方法,我在内核参数中指定了LD_LIBRARY_PATH。

 虽然我们没安什么程序,但bash是有内置命令的,比如切换目录的'cd',查看

 当前目录的'pwd'。

coreutils

============ http://www.gnu.org/software/coreutils/

 > 

 < 

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/coreutils/coreutils-build

也许要先编译一遍本地版的,先看下面的解释。

$ ../coreutils-8.22/configure --prefix=/usr/app/coreutils --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --enable-install-program=arch,hostname

修改Makefile,.x.1对象,$(abs_top_builddir) 改 /home/spy/Work/sources/coreutils

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/coreutils/coreutils

 --------------------------------------------------------------------------------

 --enable-install-program=arch,hostname

默认不安那2个,这样就安了。

coreutils里面有我最喜欢的'ls'命令,编译完后,可在开发板中验证下。

linux-pam

============ [/usr] http://linux-pam.org/

 > 

 < util-linux,libcap,

 $ cd /home/spy/Work/sources/pam/linux-pam-build

 $ ../Linux-PAM-1.1.8/configure --prefix=/usr/app/linux-pam --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/pam/linux-pam

 --------------------------------------------------------------------------------

 pam与认证有关,如果没有这个,编译util-linux的时候就不会有login。

util-linux的配置中并没有指定pam的选项,所以安装后,我把pam复制一份

 放到我交叉编译器搜索库的目录中了。

 我也尝试过把gcc依赖的库放到交叉编译器搜索库的目录中,但遇到了新的问题,

 时间关系,没有研究。

pam的库中也有个la文件,根据pam所放的目录,做类似下面的修改。

libpam_misc.la

 # Libraries that this one depends upon.

 dependency_libs=' /home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/lib/libpam.la -ldl'

 include/security/

我当初记录了这个东西,有点忘了,可能是依赖pam头文件的程序在那个目录找而不是include/。

 编译其他程序的时候如果提示找不到头文件,可改下目录。

util-linux

============ ftp://ftp.kernel.org/pub/linux/utils/util-linux/

 > pam,ncurses

 < 

我这里的编译并没有用ncurses,如果你要用的话,可先看看后面我编译ncurses的步骤。

$ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/util-linux/util-linux-build

 $ ../util-linux-2.24.1/configure --prefix=/usr/app/util-linux --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --without-ncurses

 $ make

 $ su

 # make install DESTDIR=/home/spy/Work/sources/util-linux/util-linux

 --------------------------------------------------------------------------------

 --without-ncurses

我当初还没编译ncurses,所以加了这个选项,我不知道ncurses是干什么的,这样等以后

 出问题的时候就知道它是干什么的了。

libcap

============ https://sites.google.com/site/fullycapable/

 > pam

 < systemd,

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

将makefile要引入的文件做如下修改。

CC := arm-none-linux-gnueabi-gcc

 BUILD_CC := gcc

 AR := arm-none-linux-gnueabi-ar

 RANLIB := arm-none-linux-gnueabi-ranlib

 LIBATTR := no

 $ cd /home/spy/Work/sources/libcap/libcap-2.24

 $ make

 $ make prefix=/usr/app/libcap lib=lib FAKEROOT=/home/spy/Work/sources/libcap/libcap install

 --------------------------------------------------------------------------------

完成以上步骤,复制一份和交叉编译器的库放到一起。

systemd

========== [/usr] http://www.freedesktop.org/wiki/Software/systemd/

 > libcap

 < 

 $ export PATH=$PATH:/home/spy/Software/arm-2013.11/bin

 $ cd /home/spy/Work/sources/systemd/systemd-build

修改configure,避免rpl_malloc的错误

  if test "$cross_compiling" = yes; then :

   ac_cv_func_malloc_0_nonnull=no 改成 yes

 $ ../systemd-211/configure --prefix=/usr/app/systemd --with-rootprefix=/usr/app/systemd/root --build=x86_64-unknown-linux-gnu --host=arm-none-linux-gnueabi --disable-seccomp --disable-blkid --disable-kmod --disable-pam --disable-libcryptsetup --disable-audit --disable-acl --disable-xattr --disable-selinux --disable-xz --disable-tcpwrap --disable-gcrypt --disable-qrencode --disable-microhttpd --disable-python-devel --without-python --disable-gudev --disable-apparmor --disable-dbus

 $ make

 $ make install DESTDIR=/home/spy/Work/sources/systemd/systemd

 --------------------------------------------------------------------------------

 --with-rootprefix=/usr/app/systemd/root

由于安装的时候会有一些东西安装在了app文件夹之外,指定这个选项为安装路径内部就可以了,

root是我随便起的,但最好与其他文件夹独立。

 后面那些都是可选的软件包,我全禁用了。

 今天一看,竟然有个kmod,我可以告诉你,我构建完的系统好像不能自动载入模块,也许和这个有关吧。

kmod我后面也安了。

--------------------------------------------------------------------------------

编译时看到了很多这样的信息,不知道是什么:

libsystemd_internal_la-bus-message.o (symbol from plugin): warning: memset used with constant zero length parameter; this could be due to transposed parameters

 /home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/include/bits/poll2.h: In function 'bus_poll':

 /home/spy/Software/arm-2013.11/arm-none-linux-gnueabi/libc/usr/include/bits/poll2.h:71:2: warning: call to '__ppoll_chk_warn' declared with attribute warning: ppoll called with fds buffer too small file nfds entries [enabled by default]

   return __ppoll_chk (__fds, __nfds, __timeout, __ss, __bos (__fds));

 /*------------------------------------------------------------------------------

曾经没有login时遇到的问题,

localhost login: root

&nbs

http://bbs.ickey.cn/group-topic-id-26263-dialog-1.html#postlist

继续阅读