最近想深入学习下Linux,以前对这个牛逼的东西了解不多,只是一些基本的、常用的操作。很久以前就知道有个LFS的东东,就是从头编译一个完整的Linux操作系统,于是就参照网上的教程,自己跟着学一学,顺便也加深对操作系统架构方面的了解。
参考文档 http://www.ha97.com/book/lfs-book-6.6/index.html
(一)背景介绍
LFS,即Linux from Scratch,简单说就是从零开始,自己定制编译一个Linux操作系统。听起来很牛逼,做起来其实挺简单,基本工作就是从网上下载相关的软件包,在一个宿主系统上交叉编译,首先制作编译工具链,然后用工具链编译其他软件,最后配置各种脚本等,完成一个操作系统的构建。
具体参考http://lfs.linuxsir.org/main/
http://www.linuxfromscratch.org/
http://baike.baidu.com/view/366312.htm
(二)基本概念
1、交叉编译:即在一个平台上生成另一个平台上的可执行代码,常用于嵌入式系统中。
2、宿主机(host):我们需要选择一台Linux主机作为宿主机,用来编译目标机的基础软件包。
3、目标机(target):运行编译出来的代码的机器,也就是我们定制的Linux系统。
4、平台描述:类似于x86_64-intel-Linux,描述了目标机的平台信息。
(三)准备工作
1、需要下载的软件包及补丁
http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.8.tar.bz2
http://ftp.gnu.org/gnu/m4/m4-1.4.13.tar.bz2
http://ftp.gnu.org/gnu/make/make-3.81.tar.bz2
http://download.savannah.gnu.org/releases/man-db/man-db-2.5.6.tar.gz
http://www.kernel.org/pub/linux/docs/manpages/Archive/man-pages-3.23.tar.bz2
http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.11.1.tar.bz2
http://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.bz2
ftp://ftp.gnu.org/gnu/ncurses/ncurses-5.7.tar.gz
http://ftp.gnu.org/gnu/patch/patch-2.6.1.tar.bz2
http://cpan.org/src/5.0/perl-5.10.1.tar.bz2
http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
http://procps.sourceforge.net/procps-3.2.8.tar.gz
http://prdownloads.sourceforge.net/psmisc/psmisc-22.10.tar.gz
http://ftp.gnu.org/gnu/readline/readline-6.1.tar.gz
http://ftp.gnu.org/gnu/sed/sed-4.2.1.tar.bz2
ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-4.1.4.2.tar.bz2
http://www.infodrom.org/projects/sysklogd/download/sysklogd-1.5.tar.gz
ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/sysvinit-2.86.tar.gz
http://ftp.gnu.org/gnu/tar/tar-1.22.tar.bz2
http://prdownloads.sourceforge.net/tcl/tcl8.5.8-src.tar.gz
http://ftp.gnu.org/gnu/texinfo/texinfo-4.13a.tar.gz
http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev-151.tar.bz2
http://www.linuxfromscratch.org/lfs/downloads/6.6/udev-config-20100128.tar.bz2
http://www.kernel.org/pub/linux/utils/util-linux-ng/v2.17/util-linux-ng-2.17.tar.bz2
ftp://ftp.vim.org/pub/vim/unix/vim-7.2.tar.bz2
ftp://ftp.vim.org/pub/vim/extra/vim-7.2-lang.tar.gz
http://www.zlib.net/zlib-1.2.3.tar.bz2
http://www.linuxfromscratch.org/patches/lfs/6.6/bzip2-1.0.5-install_docs-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/coreutils-8.4-i18n-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/coreutils-8.4-uname-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/diffutils-2.8.1-i18n-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/expect-5.43.0-spawn-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/expect-5.43.0-tcl_8.5.5_fix-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/flex-2.5.35-gcc44-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/gcc-4.4.3-startfiles_fix-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/gettext-0.17-upstream_fixes-2.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/grep-2.5.4-debian_fixes-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/kbd-1.15.1-backspace-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/make-3.81-upstream_fixes-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/patch-2.6.1-test_fix-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/perl-5.10.1-libc-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/perl-5.10.1-utf8-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/procps-3.2.8-watch_unicode-1.patch
http://www.linuxfromscratch.org/patches/lfs/6.6/vim-7.2-fixes-5.patch
部分软件包按照上面的url不能下载,可以到google上搜索下载。
2、准备文件系统
(1)在宿主Linux上划出一块空闲分区,我是在虚拟机上做实验,就直接增加一块10G硬盘,在系统中显示为/dev/sdb,使用fdisk工具将硬盘分成8G的数据区和2G的swap分区,分别是/dev/sdb1和/dev/sdb2。
(2)对分区分别进行格式化
mkfs.ext3 /dev/sdb1
mkswap /dev/sdb2
(3)将/dev/sdb1挂载到/mnt/lfs目录下
export LFS=/mnt/lfs
mkdir $LFS
mount -t ext3 /dev/sdb1 $LFS
/sbin/swapon -v /dev/sdb2
(4)创建源码包目录和工具链目录
sources目录用于存放下载的软件包源代码,构建工具链时,单独编译每个软件包最好新建一个build目录进行编译,然后设置prefix安装到/tools目录下,安装完成后需要将源代码目录和build目录删除,以免多次编译时相互影响。
mkdir $LFS/sources
chmod a+wt $LFS/sources
mkdir $LFS/tools tools目录用于存放目标机的编译工具链,以便于区分宿主机的环境
ln -s $LFS/tools / 在宿主机上创建tools目录的符号连接
(5)创建专门的lfs用户
在编译过程中,为了避免宿主系统环境的影响,最好是另外建立一个lfs用户,以保证编译环境的干净。
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
passwd lfs
chown -v lfs:lfs $LFS
chown -v lfs $LFS/tools
chown -v lfs $LFS/sources
(6)设置lfs用户的环境变量
在这里有.bash_profile和.bashrc两个文件,.bash_profile为登录shell设置环境变量,.bashrc为非登录shell设置环境变量。
在lfs的.bash_profile中写入以下内容:
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$' /bin/bash
在.bashrc中写入以下内容:
set +h
umask 22
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu 设置平台描述,用在交叉编译时
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL LFS_TGT PATH
(四)编译工具链
工具链是一组独立于宿主系统的工具集,用来编译目标机上的其他软件,主要包括gcc,binutils,glibc等几个包。
1、binutils
binutils是一组二进制工具集,包括addr2line ar gprof nm objcopy objdump ranlib size strings strip等(包含连接器,汇编器,反汇编器等),可用于对编译好的二进制文件进行处理。gcc必须和binutils一起才能正常运行。
Binutils 将汇编器和连接器安装在两个位置: /tools/bin
和 /tools/$LFS_TGT/bin,连接器主要用于库文件的搜索路径,
ld --verbose | grep SEARCH可以显示当前搜索路径和顺序。gcc必须跟连接器一起使用,可以用命令
gcc -print-prog-name=ld
查看gcc使用哪个标准连接器。
创建单独的编译目录:
mkdir -v ../binutils-build
cd ../binutils-build
配置binutils:
../binutils-2.20/configure \
--target=$LFS_TGT --prefix=/tools \
--disable-nls --disable-werror
如果是X86_64平台,需要执行mkdir -v /tools/lib && ln -sv lib /tools/lib64
make
make install
2、GCC
GCC是Linux下的标准编译器,但是需要跟Binutils 提供的二进制工具一起使用。
解压缩依赖的gmp和mpfr:
tar -jxf ../mpfr-2.4.2.tar.bz2
mv mpfr-2.4.2 mpfr
tar -jxf ../gmp-5.0.0.tar.bz2
mv gmp-5.0.0 gmp
创建单独的编译目录:
mkdir ../gcc-build
cd ../gcc-build
配置GCC:
../gcc-4.4.3/configure \
--target=$LFS_TGT --prefix=/tools \
--disable-nls --disable-shared --disable-multilib \
--disable-decimal-float --disable-threads \
--disable-libmudflap --disable-libssp \
--disable-libgomp --enable-languages=c
make
make install
建立Glibc对libgcc_eh.a的依赖:
ln -vs libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'
3、Glibc
Glibc是GUN的标准C库,编译应用程序可能会依赖于这些C库。
从Linux内核中提取Header,为Glibc使用:
make mrproper
make headers_check
make INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* /tools/include
创建单独的编译目录:
mkdir -v ../glibc-build
cd ../glibc-build
配置Glibc:
../glibc-2.11.1/configure --prefix=/tools \
--host=$LFS_TGT --build=$(../glibc-2.11.1/scripts/config.guess) \
--disable-profile --enable-add-ons \
--enable-kernel=2.6.18 --with-headers=/tools/include \
libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes
make
make install
4、按照步骤,重新编译binutils和gcc。
然后依次安装
Tcl-8.5.8
Expect-5.43.0
DejaGNU-1.4.4
Ncurses-5.7
Bash-4.1
Bzip2-1.0.5
Coreutils-8.4
Diffutils-2.8.1
Findutils-4.4.2
Gawk-3.1.7
Gettext-0.17
Grep-2.5.4
Gzip-1.4
M4-1.4.13
Make-3.81
Patch-2.6.1
Perl-5.10.1
Sed-4.2.1
Tar-1.22
Texinfo-4.13a
安装完成后,就完成了一个包含基本工具链的操作系统。