一. 准备工作
1. 装有Linux宿主系统的树莓派主板,可参考 Raspberry Pi(树莓派)上安装Raspbian(无路由器,无显示器)
2. 参考网址:Linux From Scratch on the Raspberry Pi
3. 参考网址:Linux From Scratch Version Development
4. 参考文档:LFS-BOOK-SVN-20161221.pdf
到Linux公社资源站下载:
——————————————分割线——————————————
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2017年资料/1月/14日/Raspberry Pi(树莓派)上从零开始构建Linux系统(简称PiLFS)/
下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm
——————————————分割线——————————————
二. PiLFS 目标架构
PiLFS主要支持 ARM(64位)的目标架构。
假如按照本文的默认方式构建,那么你将得到一个“纯” 64 位系统————这意味着你仅能够执行64 位的程序。
三. 宿主系统需求
1. 如果宿主系统是Raspbian,设置 root 密码,并且以root用户登录
sudo passwd root
su - root
2. 请执行以下命令,查看宿主机的各个软件包的版本以及编译环境是否准备妥当:
cat > version-check.sh << “EOF”
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash –version | head -n1 | cut -d” ” -f2-4
MYSH=$(readlink -f /bin/sh)
echo “/bin/sh -> $MYSH”
echo $MYSH | grep -q bash || echo “ERROR: /bin/sh does not point to bash”
unset MYSH
echo -n “Binutils: “; ld –version | head -n1 | cut -d” “ -f3-
bison –version | head -n1
if [ -h /usr/bin/yacc ]; then
echo “/usr/bin/yacc -> `readlink -f /usr/bin/yacc`”;
elif [ -x/usr/bin/yacc ]; then
echo yacc is `/usr/bin/yacc –version | head -n1`
else
echo “yacc not found”
fi
bzip2 –version2>&1 < /dev/null | head -n1 | cut -d” ” -f1,6–
echo -n “Coreutils: “; chown –version | head -n1 | cut -d”)” -f2
diff –version | head -n1
find –version | head -n1
gawk –version | head -n1
if [ -h /usr/bin/awk ]; then
echo “/usr/bin/awk -> `readlink -f /usr/bin/awk`”;
elif [ -x/usr/bin/awk ]; then
echo awk is `/usr/bin/awk –version | head -n1`
else
echo “awk not found”
fi
gcc –version | head -n1
g++ –version | head -n1
ldd –version | head -n1 | cut -d” ” -f2- # glibc version
grep –version | head -n1
gzip –version | head -n1
cat/proc/version
m4 –version | head -n1
make –version | head -n1
patch –version | head -n1
echo Perl `perl -V:version`
sed –version | head -n1
tar –version | head -n1
makeinfo –version | head -n1
xz –version | head -n1
echo ‘int main(){}’ > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
then echo “g++ compilation OK”;
else echo “g++ compilation failed”; fi
rm -f dummy.c dummy
EOF
bash version-check.sh
View Code
a. 如果宿主系统是Raspbian,你会发现缺少了四个包,使用命令行增加:
apt-get update
apt-get install bison gawk m4 texinfo
b. 同时,/bin/sh 是指向dash,使用命令行修改指向bash:
ln -sf bash /bin/sh
3. 同时,还请进行库文件的一致性检查,这些文件应该要么都在或者是都缺失,而不应该只有一两个。
cat > library-check.sh << “EOF”
#!/bin/bash
for lib in lib{gmp,mpfr,mpc}.la; do
echo $lib: $(if find /usr/lib* -name $lib|
grep -q$lib;then :;else echo not;fi) found
done
unset lib
EOF
bash library-check.sh
View Code
如果宿主系统是Raspbian,这些库文件都是缺失的,不用管它
四. 创建新分区
1. 宿主系统下安装分区工具 gparted,命令:
apt-get install gparted
2. 利用 gparted 重新划分TF卡,划出一个LFS系统分区,我的TF卡是分为:
/dev/mmcblk0p1 64M FAT32 boot分区
/dev/mmcblk0p2 16.9G EXT4 宿主系统分区
/dev/mmcblk0p3 2G Swap 交换分区
/dev/mmcblk0p4 10G EXT4 LFS系统分区
五. 挂载新分区
export LFS=/mnt/lfs mkdir -pv $LFS mount -v -t ext4 /dev/mmcblk0p4 $LFS # 如果你正在使用交换分区,用 swapon 命令确保它已经启用 /sbin/swapon -v /dev/mmcblk0p3
六. 软件包与补丁
1. 以 root
用户执行下面的命令创建$LFS/sources目录
mkdir -v $LFS/sources
2. 设置目录的写权限和粘滞模式
chmod -v a+wt $LFS/sources
“粘滞模式”意思是就算有多个用户对某个目录有写权限,仍然只有该文件的主人能删除一个粘滞目录里的文件。
3. 下载构建PiLFS需要的软件包和补丁
wget http://www.intestinate.com/pilfs/scripts/wget-list
wget -i wget-list -P $LFS/sources
七. 最后的准备工作
1. 创建 $LFS/tools 文件夹
# 以 root 用户运行以下的命令: # 编译的临时工具会安装到 $LFS/tools 文件夹,不会成为最终 LFS 系统的一部分。 mkdir -v $LFS/tools
2. 在宿主系统中创建 /tools
的符号链接,将其指向$LFS/tools
# 以 root 用户运行以下的命令: # 创建的符号链接使得编译的工具链总是指向 /tools 文件夹。 ln -sv $LFS/tools /
3. 添加lfs用户
# 以 root 用户运行以下命令来添加新组和新用户: # 当以 root 用户登录时,犯一个小错误可能会破坏或摧毁整个系统。 groupadd lfs # 添加新组 useradd -s /bin/bash -g lfs -m -k /dev/null lfs # 添加新用户 passwd lfs # 为用户设置密码 chown -v lfs $LFS/tools # 赋予了访问 $LFS/tools 文件夹的所有权限 chown -vR lfs $LFS/sources # 赋予了访问 $LFS/sources 文件夹及子文件的所有权限 su - lfs # 切换用户
4. 设置环境
# 以 lfs 用户登录运行以下两个命令,为 bash shell 创建两个开机启动的文件。 # 当以 lfs 用户身份登录时,初始 shell 通常是一个可登录的 shell # 它先读取宿主机的 /etc/profile 文件(很可能包括一些设置和环境变量),然后是 .bash_profile 文件 # .bash_profile 文件使用完全空环境的 shell 代替运行中的 shell cat > ~/.bash_profile << "EOF" exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash EOF # 新的 shell 实例是一个非登录 shell,不会读取 /etc/profile 或者 .bash_profile 文件,而是读取 .bashrc 文件 cat > ~/.bashrc << "EOF" set +h umask 022 LFS=/mnt/lfs LC_ALL=POSIX LFS_TGT=$(uname -m)-lfs-linux-gnueabihf PATH=/tools/bin:/bin:/usr/bin export LFS LC_ALL LFS_TGT PATH EOF # 启用配置文件 source ~/.bash_profile
更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2017-01/139538p2.htm
七. 构建临时系统
1. 通用编译指南
a. 确认是否正确设置了 LFS
环境变量
echo $LFS
b. 假定你已经正确地设置了宿主系统需求和符号链接
c. 对于每个软件包:
(1). 确保解压软件包时你使用的是 lfs 用户
(2). 除非特别说明,删除解压出来的目录和所有编译过程中生成的 build
目录
2. 执行shell脚本,完成临时系统的构建
cd $LFS/sources chmod +x ch5-build.sh ./ch5-build.sh
3. 改变属主
以后部分的命令都必须以 root
用户身份执行而不再是 lfs
用户。另外,再次确认下 $LFS 变量在 root 用户环境下也有定义。
当前,$LFS/tools
目录属于 lfs
用户,通过下面的命令将 $LFS/tools
目录的属主改为 root
用户:
su - root
export LFS=/mnt/lfs
chown -R root:root $LFS/tools
八. 构建LFS系统
1. 准备虚拟内核文件系统
内核会挂载几个文件系统用于自己和用户空间程序交换信息。这些文件系统是虚拟的,并不占用实际磁盘空间,
它们的内容会放在内存里。
mkdir -pv $LFS/{dev,proc,sys,run} mknod -m 600 $LFS/dev/console c 5 1 mknod -m 666 $LFS/dev/null c 1 3 mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9
mount -v --bind /dev $LFS/dev mount -vt devpts devpts $LFS/dev/pts -o gid=5,mode=620 mount -vt proc proc $LFS/proc mount -vt sysfs sysfs $LFS/sys mount -vt tmpfs tmpfs $LFS/run if [ -h $LFS/dev/shm ]; then mkdir -pv $LFS/$(readlink $LFS/dev/shm) fi
2. 进入 Chroot 环境
从这里以后,就不再需要 LFS
变量了,因为后面所有工作都将被限定在 LFS 文件系统里。
chroot "$LFS" /tools/bin/env -i \ HOME=/root \ TERM="$TERM" \ PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin /tools/bin/bash --login +h
3. 创建目录
# 现在准备创建 LFS 文件系统里的一些目录结构。使用下面的命令创建一个标准的目录树: # 这个目录树是基于文件系统目录结构标准(FHS) mkdir -pv /{bin,boot,etc/{opt,sysconfig},home,lib/firmware,mnt,opt} mkdir -pv /{media/{floppy,cdrom},sbin,srv,var} install -dv -m 0750 /root install -dv -m 1777 /tmp /var/tmp mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src} mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man} mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo} mkdir -v /usr/libexec mkdir -pv /usr/{,local/}share/man/man{1..8} case $(uname -m) in x86_64) mkdir -v /lib64 ;; esac mkdir -v /var/{log,mail,spool} ln -sv /run /var/run ln -sv /run/lock /var/lock mkdir -pv /var/{opt,cache,lib/{color,misc,locate},local}
4. 创建必需的文件和符号链接
ln -sv /tools/bin/{bash,cat,echo,pwd,stty} /bin ln -sv /tools/bin/perl /usr/bin ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib ln -sv /tools/lib/libstdc++.so{,.6} /usr/lib sed 's/tools/usr/' /tools/lib/libstdc++.la > /usr/lib/libstdc++.la ln -sv bash /bin/sh ln -sv /proc/self/mounts /etc/mtab # root 用户的实际密码(这里的 “x” 只是占位符)将在后面创建。 cat > /etc/passwd << "EOF" root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/dev/null:/bin/false daemon:x:6:6:Daemon User:/dev/null:/bin/false messagebus:x:18:18:D-Bus Message Daemon User:/var/run/dbus:/bin/false nobody:x:99:99:Unprivileged User:/dev/null:/bin/false EOF cat > /etc/group << "EOF" root:x:0: bin:x:1:daemon sys:x:2: kmem:x:3: tape:x:4: tty:x:5: daemon:x:6: floppy:x:7: disk:x:8: lp:x:9: dialout:x:10: audio:x:11: video:x:12: utmp:x:13: usb:x:14: cdrom:x:15: adm:x:16: messagebus:x:18: systemd-journal:x:23: input:x:24: mail:x:34: nogroup:x:99: users:x:999: EOF exec /tools/bin/bash --login +h touch /var/log/{btmp,lastlog,faillog,wtmp} chgrp -v utmp /var/log/lastlog chmod -v 664 /var/log/lastlog chmod -v 600 /var/log/btmp
5. 执行shell脚本,完成LFS系统的构建
cd /sources chmod +x ch6-build.sh ./ch6-build.sh
master.tar.gz:交叉编译好的二进制内核、内核模块、bootloader、GPU(VideoCore)固件
可根据脚本提示可选择的安装、升级。
6. 再次清理无用内容
logout chroot $LFS /tools/bin/env -i \ HOME=/root TERM=$TERM PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin /tools/bin/bash --login /tools/bin/find /usr/lib -type f -name \*.a \ -exec /tools/bin/strip --strip-debug {} ';' /tools/bin/find /lib /usr/lib -type f -name \*.so* \ -exec /tools/bin/strip --strip-unneeded {} ';' /tools/bin/find /{bin,sbin} /usr/{bin,sbin,libexec} -type f \ -exec /tools/bin/strip --strip-all {} ';'
7. 清理
rm -rf /tmp/* logout
chroot "$LFS" /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash --login rm -rf /tools
rm -f /usr/lib/lib{bfd,opcodes}.a rm -f /usr/lib/libbz2.a rm -f /usr/lib/lib{com_err,e2p,ext2fs,ss}.a rm -f /usr/lib/libltdl.a rm -f /usr/lib/libfl.a rm -f /usr/lib/libfl_pic.a rm -f /usr/lib/libz.a
九. 系统配置
1. 安装 LFS-Bootscripts-20150222
软件包包含一套在 LFS 系统启动和关闭时的启动和停止脚本。
cd /sources
tar -jxf lfs-bootscripts-20150222.tar.bz2
cd lfs-bootscripts-20150222
make install
cd /sources
rm -rf lfs-bootscripts-20150222
2. 配置系统主机名称
echo "lfs" > /etc/hostname
3. 创建 /etc/hosts
文件
cat > /etc/hosts << "EOF"
# Begin /etc/hosts (network card version)
127.0.0.1 localhost
# End /etc/hosts (network card version)
EOF
4. 配置 Sysvinit
内核初始化期间,第一个运行的程序默认是SysVinit,这个程序读取/etc/inittab
文件
cat > /etc/inittab << "EOF"
# Begin /etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/init.d/rc S
l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
su:S016:once:/sbin/sulogin
1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600
# End /etc/inittab
EOF
View Code
5. 安装 PiLFS-Bootscripts-20160219
软件包包含脚本的集合,以及针对树莓派硬件的一些修复
cd /sources
tar -Jxf pilfs-bootscripts-20160219.tar.xz
cd pilfs-bootscripts-20160219
make install-networkfix install-swapfix install-fake-hwclock install-switch-cpu-governor
cd /sources
rm -rf pilfs-bootscripts-20160219
6. 系统区域设置
cat > /etc/locale.conf << "EOF"
LANG=zh_CN.GB18030
EOF
7. 创建 /etc/inputrc 文件
inputrc
文件的作用是告知系统应该以怎样的键盘布局处理键盘
cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>
# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off
# Enable 8bit input
set meta-flag On
set input-meta On
# Turns off 8th bit stripping
set convert-meta Off
# Keep the 8th bit for display
set output-meta On
# none, visible or audible
set bell-style none
# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word
# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line
# End /etc/inputrc
EOF
View Code
8. 创建 /etc/shells 文件
shells
文件是当前系统所有可用 shell 的列表文件
cat > /etc/shells << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF
9. LFS官方文档中还包含了其它可选配置,可按需添加
十. 让LFS系统可引导
1. 创建 /etc/fstab 文件
将宿主系统的分区放到 /home 目录下,第一次引导lfs系统后将不得不清除宿主系统
cat > /etc/fstab << "EOF"# Begin /etc/fstab
# file system mount-point type options dump fsck
# order
/dev/mmcblk0p1 /boot vfat defaults 0 0 /dev/mmcblk0p2 /home ext4 defaults,noatime 0 1 /dev/mmcblk0p3 swap swap pri=1 0 0
/dev/mmcblk0p4 / ext4 defaults,noatime 0 2 proc /proc proc nosuid,noexec,nodev 0 0 sysfs /sys sysfs nosuid,noexec,nodev 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /run tmpfs defaults 0 0 devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
# End /etc/fstab EOF
2. 内核和引导程序
当你可能可以编译你自己的Linux内核作为构建LFS的一部分时,强烈建议你确保系统首先正确的引导树莓派发行版的内核。
树莓派上没有GRUB,我们代替依赖树莓派发行版的 bootloader 去引导。
退出chroot,编辑 /boot/cmdline.txt
,将 root=/dev/mmcblk0p2 改为
root=/dev/mmcblk0p4
十. 最后
1. 创建 /etc/lfs-release
文件
cat > /etc/lsb-release << "EOF" DISTRIB_ID="Pi Linux From Scratch" DISTRIB_RELEASE="LFS-BOOK-SVN-20161221" DISTRIB_CODENAME="kevin" DISTRIB_DESCRIPTION="Pi Linux From Scratch" EOF
2. 安装配置 dhcpcd
cd /sources tar -Jxf dhcpcd-6.11.5.tar.xz cd dhcpcd-6.11.5 ./configure --libexecdir=/lib/dhcpcd \ --dbdir=/var/lib/dhcpcd && make make install cd /sources rm -rf dhcpcd-6.11.5
# 有线网络配置
cat > /etc/sysconfig/ifconfig.eth0 << "EOF"
ONBOOT="no"
IFACE="eth0"
SERVICE="dhcpcd"
DHCP_START="-b -q"
DHCP_STOP="-k"
EOF
# 无线网络配置
cat > /etc/sysconfig/ifconfig.wlan0 << "EOF"
ONBOOT="yes"
IFACE="wlan0"
SERVICE="wpa"
# Additional arguments to wpa_supplicant
WPA_ARGS=""
WPA_SERVICE="dhcpcd"
DHCP_START="-b -q"
DHCP_STOP="-k"
EOF
# wifi配置
cat > /etc/sysconfig/wpa_supplicant-wlan0.conf << "EOF"
network={
ssid="WiFi-name1"
psk="WiFi-password1"
priority=5
}
EOF
3. 安装 OpenSSH
# openssh依赖于openssl库,先安装openssl
cd /sources tar -zxf openssl-1.0.2j.tar.gz cd openssl-1.0.2j ./config --prefix=/usr \ --openssldir=/etc/ssl \ --libdir=lib \ shared \ zlib-dynamic && make depend && make make MANDIR=/usr/share/man MANSUFFIX=ssl install && install -dv -m755 /usr/share/doc/openssl-1.0.2j && cp -vfr doc/* /usr/share/doc/openssl-1.0.2j cd /sources rm -rf openssl-1.0.2j
# 安装openssh cd /sources tar -zxf openssh-7.4p1.tar.gz cd openssh-7.4p1 install -v -m700 -d /var/lib/sshd && chown -v root:sys /var/lib/sshd && groupadd -g 50 sshd && useradd -c 'sshd PrivSep' \ -d /var/lib/sshd \ -g sshd \ -s /bin/false \ -u 50 sshd ./configure --prefix=/usr \ --sysconfdir=/etc/ssh \ --with-md5-passwords \ --with-privsep-path=/var/lib/sshd && make make install && install -v -m755 contrib/ssh-copy-id /usr/bin && install -v -m644 contrib/ssh-copy-id.1 /usr/share/man/man1 && install -v -m755 -d /usr/share/doc/openssh-7.4p1 && install -v -m644 INSTALL LICENCE OVERVIEW README* /usr/share/doc/openssh-7.4p1 cd /sources
rm -rf openssh-7.4p1
# 系统启动时开启ssh服务
cd /sources
tar -Jxf blfs-bootscripts-20160902.tar.xz
cd blfs-bootscripts-20160902
make install-sshd
cd /sources
rm -rf blfs-bootscripts-20160902
4. 重启系统
logout umount -v $LFS/dev/pts umount -v $LFS/dev umount -v $LFS/run umount -v $LFS/proc umount -v $LFS/sys umount -v $LFS shutdown -r now
十一. 如何将PiLFS做成TF卡镜像
1. 需要一台装有Linux系统的PC机
2. 将TF卡上的boot分区和PiLFS分区的内容分别复制到PC机上的bootfiles和lfsfiles文件夹下
3. 利用 gparted 格式化并重新划分TF卡:
/dev/sdb1 50M FAT32 boot分区
/dev/sdb2 2G EXT4 PiLFS分区
4. 使用 parted -l 命令查看并取得boot分区的开始位置(bootStart)和PiLFS分区的结束位置(lfsEnd)
5. 将bootfiles和lfsfiles文件夹下的内容分别复制到重新划分的boot分区和PiLFS分区
6. 利用dd命令将TF卡做成镜像:
dd if=/dev/sdb of=mylfs.img bs=1M count=2098
其中,bs为bootStart的值,count为lfsEnd的值
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139538.htm