在BeagleBone Black上构建Linux 0.1

本文详细介绍了在BeagleBoneBlack开发板上构建Linux系统的过程,包括选择启动引导程序U-Boot、编译Linux内核及应用程序等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我构建的目标平台为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,用你的包管理器安上就好了。

/*------------------------------------------------------------------------------
摘自TI的wiki,让你了解MLO和u-boot.img是什么。
 大概是AM335X芯片中的程序较小,只为了4种启动方式初始化,
 然后找到MLO,运行MLO进一步初始化,如DDR3内存。
MLO最后找到u-boot.img,运行之。u-boot.img这个名字应该是在MLO的代码中指定的。
 提示:TI的StarterWare中的2个文件叫MLO和app。

Two stage U-Boot design

 This section gives an overview of the two stage U-Boot approach adopted for AM335X.

 The size of the internal RAM in AM335X is 128KB out of which 
 18KB at the end is used by the ROM code. Also, 
 1 KB at the start (0x402f0000 - 0x402f0400) is secure and it cannot be accessed 
 This places a limit of 109KB on the size of the U-Boot binary which 
 the ROM code can transfer to the internal RAM and use as an initial stack 
 before initialization of DRAM.

 Since it is not possible to squeeze in all the functionality 
 that is normally expected from U-Boot in < 110KB (after setting aside some space 
 for stack, heap etc) a two stage approach has been adopted. 
 Initial stage initalize only the required boot devices (NAND, MMC, I2C etc); 
 2nd full stage initall all other devices (ethernet, timers, clocks etc). 
 The 1st binary is generated MLO and the 2nd stage is generated as u-boot.img. 
 ------------------------------------------------------------------------------*/

编译完后,现在就可以找找成就感了,
 将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个文件夹中。
/*------------------------------------------------------------------------------
安装modules的时候,可能会提示depmod出问题,据说正常,那不是处理交叉编译的模块的。
 但我还是看到了depmod后应该出现的modules.dep文件。
depmod是用来构建模块依存关系的,目的是,当用insmod装载某模块的时候,可能会失败,
 因为这个模块依赖的其他模块还没有装入内核,depmod构建完依赖关系后,用另外一个命令
 装载模块,即可自动装载模块所依赖的其他模块。
------------------------------------------------------------------------------*/

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

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

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

下面可以验证了。
 将uImage文件,dts文件夹复制到SD卡第二个分区的/boot/里。
 其实dts中应该只需am335x-boneblack.dtb。

 启动开发板前应该了解下U-Boot如何载入Linux。
/*------------------------------------------------------------------------------
U-Boot中最关键的环境变量
bootcmd: This variable defines a command string that is automatically executed 
          when the initial countdown is not interrupted.
          This command is only executed when the variable bootdelay is also defined!
 bootargs: The contents of this variable are passed to the Linux kernel as boot 
           arguments (aka "command line"). 

 U-Boot中最关键的命令
run    - run commands in an environment variable

 U-Boot启动后会运行bootcmd里的命令,所以要研究的话,从bootcmd开始。
------------------------------------------------------------------------------*/
提示:我的研究在后面。现在可不必研究直接看我的处理。

 编译后的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放到一起,内容如下。
 该文件中的环境变量会覆盖掉默认的环境变量。
/*
bootfile=uImage
 loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/dts/${fdtfile}
 mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootm ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
 mmcroot=/dev/mmcblk0p2 rw
 mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} init=/usr/lib/systemd/systemd

 */
一共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
 /*-----------------------------
 #include <stdio.h>

 int main(int argc, char *argv)
 {
   printf("Hello world!n");
   sleep(999999999);
 }

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

 $ arm-none-linux-gnueabi-gcc -o hello -static hello.c
再次启动,最后你看到的将是"Hello world!"。

/*------------------------------------------------------------------------------
我分析了U-Boot的引导过程,如下,再往下是我的演示。

gpio set 53;   //这个是点亮LED灯的,其实并没有这个,是我在其他的U-Boot中看到的。
i2c mw 0x24 1 0x3e; //这个也没有,不知干什么的,激发下你的好奇心。
mmc dev 0; //将设备切换到'0',即SD卡,其实一开始就是'0',eMMC是'1'。
mmc rescan; //应该是检测设备是否存在吧。

gpio set 54;
 load mmc 0 0x80200000 uEnv.txt;
 env import -t 0x80200000 $filesize //这2步是导入环境变量,filesize这个变量没找到。

gpio set 55;
 load mmc 0:2 0x80200000 /boot/uImage;

 gpio set 56;
 load mmc 0:2 0x80F80000 /boot/dts/am335x-boneblack.dtb;

 setenv bootargs console=ttyO0,115200n8 ${optargs} root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait init=/usr/lib/systemd/systemd
 bootm 0x80200000 - 0x80F80000;

 optargs这个环境变量也没找到,在其他U-Boot中发现是quiet,
 作用是减少了内核打印的信息,systemd打印的信息也少了。
------------------------------------------------------------------------------*/

 /*------------------------------------------------------------------------------
U-Boot# mmc dev 0
 mmc0 is current device
 U-Boot# mmc rescan
 U-Boot# load mmc 0:2 0x80200000 /boot/uImage
 3894896 bytes read in 237 ms (15.7 MiB/s)
 U-Boot# load mmc 0:2 0x80F80000 /boot/dts/am335x-boneblack.dtb
 17911 bytes read in 213 ms (82 KiB/s)
 U-Boot# setenv bootargs console=ttyO0,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait init=/usr/lib/systemd/systemd
 U-Boot# bootm 0x80200000 - 0x80F80000
 ## Booting kernel from Legacy Image at 80200000 ...
    Image Name:   Linux-3.13.5
    Image Type:   ARM Linux Kernel Image (uncompressed)
    Data Size:    3894832 Bytes = 3.7 MiB
    Load Address: 80008000
    Entry Point:  80008000
    Verifying Checksum ... OK
 ## Flattened Device Tree blob at 80f80000
    Booting using the fdt blob at 0x80f80000
    Loading Kernel Image ... OK
    Using Device Tree in place at 80f80000, end 80f875f6

 Starting kernel ...

 [    0.000000] Booting Linux on physical CPU 0x0
 [    0.000000] Initializing cgroup subsys cpuset
 [    0.000000] Initializing cgroup subsys cpu
 [    0.000000] Initializing cgroup subsys cpuacct
 [    0.000000] Linux version 3.13.5 (spy@alien) (gcc version 4.8.1 (Sourcery CodeBench Lite 2013.11-33) ) #1 SMP Sat Mar 8 20:26:55 UTC 2014

我并没有导入uEnv.txt,它是下面这个样子的。

U-Boot# load mmc 0 0x80200000 uEnv.txt
 reading uEnv.txt
 510 bytes read in 4 ms (124 KiB/s)
 U-Boot# env import -t 0x80200000
 ## Info: input data size = 966 = 0x3C6

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

下面就是应用程序了,可根据我的提示自行安排顺序,我曾经的顺序不是这样的。
 主要的过程就是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”。

/*------------------------------------------------------------------------------
build  - 构建程序的系统,在该系统中配置和编译程序。
host   - 构建后的程序运行在此系统中。
target - 编译工具为此系统生成程序。

 这个target,配置glibc不用指定,有的文档中是这样说的。
It's for use when building compiler tools, with `--host' being where they 
 will run, and `--target' what they'll produce code for.

也就是说,通常用在构建编译工具的时候,举个例子,
 如果你在你的x86_64计算机中编译gcc,运行在你的x86_64系统中,让gcc生成的程序也运行在x86_64中,
 这三个是这样的(为了突出重点,我简化了等号右边):
build=x86_64,host=x86_64,target=x86_64。
 在Arch Linux中运行'pacman -S gcc'安装的就是这种(pacman是包管理器),
 前2个条件不变,如果让gcc生成的程序运行在arm中,就像我们要用的Sourcery CodeBench Lite,那么这三个是这样的:
build=x86_64,host=x86_64,target=arm。
 第一个条件不变,如果让gcc运行在arm中,生成的程序也运行在arm中,就像后面我们要编译的,这三个是这样的:
build=x86_64,host=arm,target=arm。

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

等号右边的格式如下:

    cpu-company-system

 system可以有以下2种格式之一
    os
     kernel-os

查看源码中的config.sub文件,能看到各部分可能的值。
 运行configure的时候,如果没指定的话,configure会用config.guess这个脚本
 猜出build的值。然后host默认等于build,target默认等于host。
config.guess通常和config.sub在一起,都可单独运行的,有“--help”这个选项可用。

 在我的系统中猜测出的值为“x86_64-unknown-linux-gnu”。
 在BeagleBone Black中,结果为“armv7l-unknow-linux-gnueabihf”。这个结果应该是
 不知道的,因为我是在BeagleBone Black已经可用的系统中运行的config.guess。
 而我们的系统还没有构建出来呢,不可能运行config.guess。

 那么我们如何确定host呢,难道要看config.sub?不必。
 当build和host不同的时候,configure会启用交叉编译模式。
 它会检测以host值为前缀的编译工具,如arm-none-linux-gnueabi-gcc,然后使用这个
 带前缀的gcc。所以我们的host指定为我们交叉编译器中命令的前缀就好了。
 我尝试过了,如果host是“abcdefg”这种,大概会提示无效的值;
 如果是“arm-none-linux-gnueabihf”这种有效的,configure会检测
arm-none-linux-gnueabihf-gcc,他是找不到的。

 既然build可以猜测出来,那是否还要指定呢,我开始就是没指定,可以的。但是autoconf手册中:
“For historical reasons, whenever you specify --host, be sure 
 to specify --build too; this will be fixed in the future.”
看来这个“future”已经到了,但我还是指定了。
------------------------------------------------------------------------------*/

我们编译程序是用在其他的系统中,如果不指定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'

 /*------------------------------------------------------------------------------
找不到*.la的问题
/usr/bin/sed: can't read /usr/app/gmp/lib/libgmp.la: No such file or directory
 libtool: link: `/usr/app/gmp/lib/libgmp.la' is not a valid libtool archive

如果没有我mpfr中的修改,编译时就会出现这个错误。
 编译mpc的时候,应该读取了mpfr中的libmpfr.la。然后根据dependency_libs中的路径
 找libgmp.la,结果找不到。
dependency_libs的前一部分,应该是由我配置时指定的--with-gmp来确定,
 而后半部分,看看安装后的gmp,也有个.la文件,文件中有个libdir,

# Directory that this library needs to be installed in:
 libdir='/usr/app/gmp/lib'

很明显,这个libdir是根据编译gmp时指定的prefix确定的。

 如果把libdir手动改成'/home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib',
 再编译mpfr,libmpfr.la中的dependency_libs就是,
# 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'

这样也不会出现lib*.la文件被moved的警告。
 由此可见,后半部分是由所依赖的.la文件中libdir确定的。
 我最后没有选择修改libdir,虽然修改libdir也可以编译成功,而且没有警告。
------------------------------------------------------------------------------*/


 
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。

/*------------------------------------------------------------------------------
编译时错误undefined reference
 warning: libisl.so.10, needed by ./.libs/libcloog-isl.so, not found (try using -rpath or -rpath-link)
 rpath的问题,解决见make前操作。

 一看和isl有关,cloog的源码中自带了一份isl,我配置时没用cloog中的,
 当出现这个错误时,我配置成用cloog中的,这样编译cloog的时候,会有编译isl的过程,
 结果编译isl的时候就有错误。
 看了一下cloog中的isl,版本低一些。
 我单独编译这个isl或者在isl官网下载同样的版本,都是出错,为了解决cloog的错误,
 我决定先解决简单一些的isl的错误入手。

>>> isl-0.12.1版本的问题

isl_polyhedron_sample
 isl_polytope_scan
 isl_polyhedron_detect_equalities
 isl_cat
 isl_closure

以上就是编译时出现过的有问题的make对象。在makefile文件中,用了下面的rpath即可解决。
-rpath /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib
 rpath是运行时搜索程序库的路径,是gcc的参数,可以写到编译后的程序中的。

 也许还有别的对象,但都用LINK
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) 
     $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) 
     $(AM_LDFLAGS) $(LDFLAGS) -o $@

更改 AM_LDFLAGS = -rpath /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib
就都解决了。

 但我发现了另一个方式,把这一个改对就可以
libisl.la: $(libisl_la_OBJECTS) $(libisl_la_DEPENDENCIES) $(EXTRA_libisl_la_DEPENDENCIES)
     $(AM_V_CCLD)$(libisl_la_LINK) -rpath /home/spy/Work/sources/gmp/gmp/usr/app/gmp/lib $(libisl_la_OBJECTS) $(libisl_la_LIBADD) $(LIBS)

我不知道这样做是否会出现什么问题,但还没遇到,除了下面没造成什么影响的。

 按这个方式修改cloog的makefile的时候,
.la文件中,安装路径里出现的应该是cloog啊,竟然是isl,我做了修改,
# Directory that this library needs to be installed in:
 libdir='/home/spy/Work/sources/isl/isl/usr/app/isl/lib'
改成
# Directory that this library needs to be installed in:
 libdir='/usr/app/cloog/lib'
 ------------------------------------------------------------------------------*/


 
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个,这样就安了。

/*------------------------------------------------------------------------------
help2man不能得到help信息
help2man: can't get `--help' info from man/chroot.td/chroot
 Try `--no-discard-stderr' if option outputs to stderr

 help2man通过目标程序--help选项的输出来生成man,而我是交叉编译,目标程序不能
 在我的系统中运行。所以我先编译了一遍本地版的,把运行make那个目录中的src文件夹
 复制到了'/home/spy/Work/sources/coreutils'。
 重新配置成交叉编译,在make之前修改makefile文件,将help2man的目标程序指定到本地版的。
------------------------------------------------------------------------------*/

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/。
 编译其他程序的时候如果提示找不到头文件,可改下目录。

/*------------------------------------------------------------------------------
‘yywrap’的问题

 搜索后这个函数在flex中,安装后,我也不太会用,
conf/pam_conv1/Makefile
 LIBS = -lfl

 doc/specs/Makefile

还有一些其他新问题,于是换策略。

conf/pam_conv1/pam_conv_l.c

 int     yywrap (void)
 {
     return 1;
 }

 doc/specs/parse_l.c

 int     yywrap (void)
 {
     return 1;
 }

就是在那2个c源文件中添加yywrap函数,
 反正felx中有个libyywrap.c,里面的函数就这个样子。
------------------------------------------------------------------------------*/


 
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是干什么的,这样等以后
 出问题的时候就知道它是干什么的了。

/*------------------------------------------------------------------------------
安装时,不能改变bin/wall的用户组为tty
我采用了安装时切换用户为root的方法。

 带pam库编译时    
cannot find the library `/usr/app/linux-pam/lib/libpam.la' or unhandled argument `/usr/app/linux-pam/lib/libpam.la'
修改libpam_misc.la中的路径,见pam中的修改。
------------------------------------------------------------------------------*/


 
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));

 /*------------------------------------------------------------------------------
配置出错时提示过的
sys/capability.h 在libcap中
pkg-config
 intltool
 gperf

后3个不是库,编译时被调用,又不像编译器那样为另一个平台生成程序,所以应该不必
 为我构建的系统编译他们,用自己Linux系统的包管理器安上就好了。

 注意pkg-config是负责寻找库的,如果用他默认的搜索路径,找到的是你正使用系统中的库,
 而不是应该用在BeagleBone Black中的库。如果像我这样把那些可选的软件包都禁用的话,
 是不需要pkg-config的。我把pkg-config通过配置选项指定到一个目录,也能编译成功。
 如果想让pkg-config找到正确的库的话,可看看它的手册,有几个环境变量可影响它搜索库
 的路径。
------------------------------------------------------------------------------*/

 /*------------------------------------------------------------------------------
终于到了真正的init程序,这么伟大的程序,竟然没找到学习的文档。我总结了一点。

systemd包含了udev。
--------------------------------------------------------------------------------
At boot time we now print warnings if: 
 /usr is on a split-off partition but not already mounted by an initrd; if 
 /etc/mtab is not a symlink to /proc/mounts; 
 CONFIG_CGROUPS is not enabled in the kernel. 
 We'll also expose this as tainted flag on the bus.

所以/etc/中应该放个mtab了。
--------------------------------------------------------------------------------
systemd对一些目录的要求。
 参见http://www.freedesktop.org/wiki/Software/systemd/FileHierarchy/

 /, /usr, /etc must be mounted when the host systemd is first invoked. This may 
 be achieved either by using the kernel's built-in root disk mounting (
 in which case /, /usr and /etc need to be on the same file system), or 
 via an initrd, which could mount the three directories from different sources.

 /bin, /sbin, /lib (and /lib64 if applicable) should reside on /, or be symlinks 
 to the /usr file system (recommended). All of them must be available 
 before the host systemd is first executed.

 /var does not have to be mounted when the host systemd is first invoked, 
 however, it must be configured so that it is mounted writable 
 before local-fs.target is reached (for example, by simply listing it in /etc/fstab).

 /tmp is recommended to be a tmpfs (default), but doesn't have to. If configured, 
 it must be mounted before local-fs.target is reached (for example, by listing it in /etc/fstab).

 /dev must exist as an empty mount point and will automatically be mounted 
 by systemd with a devtmpfs. Non-devtmpfs boots are not supported.

 /proc and /sys must exist as empty mount points and 
 will automatically be mounted by systemd with procfs and sysfs.

 /run must exist as an empty mount point and will automatically be mounted by systemd with a tmpfs.
 --------------------------------------------------------------------------------
 If a process belonging to a specific cgroup fork()s, its child will become a member of the same group.
 You can find the cgroups of a process by reading /proc/$PID/cgroup.
 cgroups hence make a very good choice to keep track of processes for babysitting purposes.
 ------------------------------------------------------------------------------*/

 /*------------------------------------------------------------------------------
又到了体验成就感的时候,目前,我们已经拥有的程序,
glibc,gmp,mpfr,mpc,isl,cloog,gcc,bash,
coreutils,linux-pam,util-linux,libcap,systemd。
 放到SD卡中。
 也许最好把SD卡中文件的用户和组改成root,但是util-linux中的wall属于tty组。
 我下面这2条命令是不全的。
# chown -R 0:0 
 # chgrp -v tty /usr/app/util-linux/bin/wall
由于有了新的程序库,而且是systemd需要用到的,所以先别急着改把init改成systemd,
 那样应该会提示找不到库的,所以先用bash,执行一下ldconfig,然后再改,
init=/usr/lib/systemd/systemd
 --------------------------------------------------------------------------------

 /etc/中的文件,目前就有个mtab,
 如果没有passwd文件,会有登陆的提示,还会让输入密码,然后就是登陆失败,所以要创建。

/etc/passwd
 root::0:0:root:/home/root:/usr/bin/bash

目前不能设置密码,设置了会登陆失败,不知为什么,可能为了安全吧。所以密码部分空着。
--------------------------------------------------------------------------------

/etc/pam.conf
 other auth    required  pam_unix.so nullok
 other account   required  pam_unix.so broken_shadow
 other session   required  pam_unix.so
 other password  required  pam_unix.so nullok

这是pam的配置文件,可看看pam的手册,内容没深入研究,是我自己看了很多配置后定的。
 如果没有配置文件,登陆时会有下面的错误,
login: PAM failure, aborting: Critical error - immediate abort

第一部分是需要pam的程序的名字,如login,改成login也可以。
 最后的nullok选项是必要的,这允许没有密码的登陆,也不知道这4个中,哪个需要,
 临时先参照别人的。

 前面说到,不能在passwd中设置密码,我本以为加了broken_shadow选项就可以了,但不是。

pam也可以在'/etc/pam.d/'中找配置文件,这个是shadow的一部分,里面不止一个配置文件。
 如果pam.d存在,则忽略pam.conf。可建个空的pam.d文件夹试试,我没研究。
--------------------------------------------------------------------------------

现在启动BeagleBone Black吧,
systemd启动后,会在/etc/中创建一个machine-id文件,
 最后systemd会启动在ttyO0上的登陆服务,提示登陆,输入root,确定后就看见bash了。

 我的systemd启动过程中会有一个服务失败,就是在另一个tty设备登陆的服务,可能是我没连
 显示器?

 一些命令,
 显示这次登陆的日志,
# journalctl -b

重启,
$ systemctl reboot

关机
$ systemctl poweroff
但我的关上后,电源指示灯还亮着,别的灯倒是灭了。
------------------------------------------------------------------------------*/

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

localhost login: root
&nbs



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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值