免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: snow888
打印 上一主题 下一主题

从 0 开始,打造自己的 Linux 。 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
41 [报告]
发表于 2012-04-15 01:46 |只看该作者
本帖最后由 snow888 于 2012-04-15 05:07 编辑

兄弟们,工具安装完成了么?

老实说,这两天我可编译得鬼火冒,一行一行的敲命令,累死了。

如果工具都装好了,那么我们接着来。

下面我们需要先安装 Coreutils , 这是一套包括显示设置在内的 linux 工具,没有这个,下面我们什么也干不了了。

安装方式一样,不重复叙述。需要主要的是,一定要采用静态编译的方式(具体的方法见前面部分)。

安装完成 Coreutils 之后,我们需要安装 Util-linux-2.12r , 这是一套 linux 的基本命令,安装完成以后。我们进入到 /My_Operation/myuser/bin 目录下,建立一个连接。

ln -sf zcmp cmp

完成了吗?

下面我们开始二次安装和编译 gcc 和 binutils 。

为什么要二次安装 gcc 和 binutils ?

还记得我们前面编译 gcc 和 binutils 的时候,是用什么工具编译的吗?对了,是用的母体系统的 gcc 编译的,这个编译过程中有大量的 fix 过程,将大量的母体的基础头文件和类库打包进入了我们的这个新生的 gcc 中,我们得完全剔除母体的影响。

来吧,我们继续。

首先清理我们的 gcc 的那些母体的垃圾文件 ,执行下面的命令(同样,我们强烈建议你编写一个脚本文件来执行)
  1. GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
  2. find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&
  3. rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
  4. unset GCC_INCLUDEDIR
复制代码
特别注意,这个动作一定要在 你自己的这个编译环境有效的情况下执行,如何确定有效?
输入 gcc -v , 如果显示的是 gcc 4.0.3 则 OK 了 ,否则,请执行俺前面给的那个 403.sh 的脚本


执行完成以后,我们在 gcc-4.0.3 的源码目录再运行如下的脚本
  1. cp -v gcc/Makefile.in{,.orig} &&
  2. sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in
复制代码
这个脚本将阻止新的编译去检查并修复(尽管不是我们想要的修复)我们的 gcc 4.0.3 的编译环境。

为了加快编译速度,我们还需要执行如下脚本。
  1. cp -v gcc/Makefile.in{,.tmp} &&
  2. sed 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp \
  3. > gcc/Makefile.in
复制代码
这个其实是让我们在普通的编译方式时也添加进 -fomit-frame-pointer 的编译选项,这将时我们在编译时不再需要执行 make bootstrap ,因为这再无必要了,我们的 gcc 就是用同一套源码编译的,还有什么必要做那种重复的检查呢?

编译并执行安装
$ ../gcc-4.0.3/configure --prefix=/My_Operation/myuser \
--with-local-prefix=/My_Operation/myuser --enable-clocale=gnu \
--enable-shared --enable-threads=posix \
--enable-__cxa_atexit

$ make BOOT_LDFLAFS="-static" LIB_PATH=/lib:/usr/lib:/usr/local/lib:/opt/lib
$ make install


论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
42 [报告]
发表于 2012-04-15 01:52 |只看该作者
悲剧,俺刚刚测试这个过程的虚拟机挂掉了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
43 [报告]
发表于 2012-04-15 05:09 |只看该作者
请特别注意这个参数:

make BOOT_LDFLAFS="-static" LIB_PATH=/lib:/usr/lib:/usr/local/lib:/opt/lib



如果不能如此指定,会造成两个方便的问题:

1、你的 gcc 在切换到虚拟环境后将不可用。
2、即使可以使用 gcc ,在默认的编译条件下,你编译出来的文件也无法执行。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
44 [报告]
发表于 2012-04-15 13:34 |只看该作者
本帖最后由 snow888 于 2012-04-15 20:25 编辑

准备好了吗?

下面我们开始来二次编译 binutils , 编译的方法没什么特别的,注意编译参数:
  1. ../binutils-2.16.1/configure --prefix=/My_Operation/myuser \
  2. --disable-nls --with-lib-path=/lib:/usr/lib:/usr/local/lib:/opt/lib
复制代码
make LDFLAFS="-all-static" LIB_PATH=/lib:/usr/lib:/usr/local/lib:/opt/lib

特别强调,在这里我们带的 LDFLAGS 参数是 "-all-static",和 编译 gcc 时一样,我们的链接参数最后指向 LIB_PATH=/lib:/usr/lib:/usr/local/lib:/opt/lib , 这个参数的含义是让我们最后形成的 ld 文件在链接我们编译的程序的时候,从 /lib:/usr/lib:/usr/local/lib:/opt/lib 这几个目录下面找动态链接库来连接。

为什么要这样做?这样做不是又回去了吗?我想说的是此 /lib:/usr/lib:/usr/local/lib:/opt/lib 非彼 /lib:/usr/lib:/usr/local/lib:/opt/lib,因为我们这个工具是在虚拟的新生系统下使用的,不是准备在我们当前的系统下使用的。

下面我们开始安装 glibc , 这个的安装路径同样指向 /My_Operation/myuser , 这个也是为我们切换到新生系统上之后使用的。当然,在安装 glibc 之前,我们不要忘记先安装 linux-libc-headers , 方法在前面有说明,不重复叙述。

然后我们开始安装 ncurses ,软件包,这个的安装路径也同样指向 /My_operation/myuser 。

好了,到现在为止,我们的新生系统的准备工作已经基本完成了。

下面我们需要安装几个工具软件包。tar 、gzip、bzip2、这几个工具包也同样安装到 /My_Operation/myuser 目录之下,当然你也可以安装到 /My_Operation/myuser/usr 目录之下,我只想强调一点,我们所有的安装都是采用第一次编译的 gcc 来实现的,同时还必须是编译成静态的。

下面我们开始安装两个系统的基本系统文件。

Coreutils 软件包,它包括一整套用于显示和设置基本系统特征的工具。这个软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser 目录之下,并且同样是静态编译。

Util-linux 软件包,它包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理驱动器,以及打开 tty 端口和处理消息。这个软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser 目录之下,并且同样是静态编译。

sed 是一个流编辑程序,在一个输入流(从一个文件或者一个管道的输入)上进行基本的文本编辑操作。这个软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser 目录之下,并且同样是静态编译。

Gawk 是一个处理文本文件的工具包。这个软件包有一个 BUG , 我们把源码改一下。

修改 config.h 文件,在其中加入如下语句。
  1. #ifndef HAVE_LANGINFO_CODESET
  2. #define HAVE_LANGINFO_CODESET 1
  3. #endif
  4. #ifndef HAVE_LC_MESSAGES
  5. #define HAVE_LC_MESSAGES 1
  6. #endif
复制代码
修改完成以后,我们进行安装,软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser 目录之下,并且同样是静态编译。

下面我们需要安装能驱动虚拟环境的系统软件包。

E2fsprogs 不陌生吧,它提供用于 ext2 文件系统的工具。它还支持 ext3 日志文件系统。

编译参数如下:
  1. ./configure --prefix=/My_Operation/myuser/usr --with-root-prefix="" \
  2. --disable-evms
复制代码
参数说明:

--with-root-prefix=""    ;;某些程序(如 e2fsck )对系统来说是非常重要的,例如,在 /usr 没有挂载的情况下。这些程序和库就应放在像 /lib 和 /sbin 这些目录中。如果没有把上面的参数传递给 E2fsprogs 的 configure 脚本,它就会把程序放在 /usr 目录下。
--disable-evms            ;; 禁止了企业卷管理系统(EVMS)插件的支持。

同样,我们采用静态编译的方式。

Psmisc 软件包,包含有用于显示进程信息的程序。软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser/usr 目录之下,并且同样是静态编译。

Shadow 软件包,包含用于在安全方式下处理密码的程序。软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser/usr 目录之下,并且同样是静态编译。

Sysklogd  软件包,包含记录系统日志信息的程序,比如内核处理意外事务的日志。方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser/usr 目录之下,并且同样是静态编译。
该软件包安装完成以后,我们在 /My_Operation/myuser/etc 下面建立 syslog.conf 文件,内容如下:
  1. auth,authpriv.* -/var/log/auth.log
  2. *.*;auth,authpriv.none -/var/log/sys.log
  3. daemon.* -/var/log/daemon.log
  4. kern.* -/var/log/kern.log
  5. mail.* -/var/log/mail.log
  6. user.* -/var/log/user.log
  7. *.emerg *
复制代码
同时,我们需要创建 /My_Operation/myuser/var/log 目录。

Sysvinit 软件包,它包含一些控制系统启动、运行、关闭的程序。软件包的安装路径、方法和我们上面讲的完全一样,也是安装到 /My_Operation/myuser/ 目录之下,并且同样是静态编译。
编译安装完成以后,我们在 /My_Operation/myuser/etc 下面创建 inittab 文件,内容如下:
  1. id:3:initdefault:
  2. si::sysinit:/etc/rc.d/init.d/rc sysinit
  3. l0:0:wait:/etc/rc.d/init.d/rc 0
  4. l1:S1:wait:/etc/rc.d/init.d/rc 1
  5. l2:2:wait:/etc/rc.d/init.d/rc 2
  6. l3:3:wait:/etc/rc.d/init.d/rc 3
  7. l4:4:wait:/etc/rc.d/init.d/rc 4
  8. l5:5:wait:/etc/rc.d/init.d/rc 5
  9. l6:6:wait:/etc/rc.d/init.d/rc 6
  10. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
  11. su:S016:once:/sbin/sulogin
  12. 1:2345:respawn:/sbin/agetty tty1 9600
  13. 2:2345:respawn:/sbin/agetty tty2 9600
  14. 3:2345:respawn:/sbin/agetty tty3 9600
  15. 4:2345:respawn:/sbin/agetty tty4 9600
  16. 5:2345:respawn:/sbin/agetty tty5 9600
  17. 6:2345:respawn:/sbin/agetty tty6 9600
复制代码
同时,我们创建 /My_Operation/myuser/etc/rc.d/init.d/rc 子目录。

看到这里,相信大家一定猜到了,我们马上就要进入我们孕育的这个新生系统了。的确,这个新生系统马上就要出来了。

有关如何切换到我们的新生系统的问题,我们下一节再讲。




论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
45 [报告]
发表于 2012-04-15 13:54 |只看该作者
本帖最后由 snow888 于 2012-04-15 13:56 编辑

在切换之前,我们先测试一个我们第二次编译的 gcc 和 binutils 程序。

我们还是利用前面的那个测试程序,先成测试一下我们的新编译器是否可以使用了

gcc -o a a.c

ldd a 看看,是否是链接的 /lib/libgcc_s.so.2 如果是的,那么恭喜你,你可以进入下面的部分了。

我们先设置一下参数。

export MYOperation=/My_Operation/myuser

创建我们的基础设备文件。
mkdir $MYOperation/dev
  1. mknod -m 600 $MYOperation/dev/console c 5 1
  2. mknod -m 666 $MYOperation/dev/null c 1 3
复制代码
挂载并填充 /dev 目录
  1. mount --bind /dev $MYOperation/dev
复制代码
挂载虚拟文件系统
  1. mount -vt devpts devpts $MYOperation/dev/pts
  2. mount -vt tmpfs shm $MYOperation/dev/shm
  3. mount -vt proc proc $MYOperation/proc
  4. mount -vt sysfs sysfs $MYOperation/sys
复制代码
下面,我们进入自己的新系统吧。让我们大喊 1、2、3 ,我们一起来。
执行下面的脚本 chg2newsys.sh
  1. chroot "$MYOperation" /bin/env -i \
  2. HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
  3. PATH=/bin:/usr/bin:/sbin:/usr/sbin \
  4. /bin/bash --login +h
  5. env
复制代码
env 命令的参数 -i 的作用是清除所有 chroot 环境变量。
重新设定 HOME, TERM, PS1, PATH 等变量的值。TERM=$TERM 设定虚拟根环境中的 TERM 的值与 chroot 外面的一样。

怎么样,进来了吗?你看到 # 操作符号了吗?恭喜你。

进入以后,我们第一个要做的是测试我们的gcc 是否可以使用,这个时候的 gcc 是我们第二次编译的 gcc 了。

来,我们还是用这个源码来测试。
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main ( void )
  4. {
  5.           puts("\n Hello world!\n");
  6.           return 0;
  7. }
复制代码
编译一下,gcc -o a a.c
怎么回事? 找不到 stdio.h 和 stdlib 头文件?找不到 puts 函数定义? 晕,在外面的时候不是好好的么? 别着急,我们进入 usr 目录,执行 ln -sf /include include
然后再次对 a.c 进行编译,怎么样,通过了吗?执行一下看看 ./a 你应该能看到打出的 Hello World!信息。

恭喜你。

下面,我们第一个要编译的就是 vim ,这玩意儿太重要了。
进入 vim70 目录直接编译,我们编译的安装路径是 /usr ,如果不出现问题,编译完成,咱们的 vim 就可以使用了。

哈哈,怎么样,下一部分,我们就开始讲解如何构建 /etc/fatab ,如何安装 grub ,如何安装 linux 内核。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
46 [报告]
发表于 2012-04-15 14:44 |只看该作者
下面我们需要基本安装设备驱动程序 UDEV 、网络程序 Inetutils、IPRoute2-2.6.16-060323 、键盘映射 Kbd-1.12 、配置文件查找程序 Less 、内核动态模块挂载程序 Module-Init-Tools 、内核启动管理程序 GRUB 、 以及 linux 内核 。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
47 [报告]
发表于 2012-04-15 21:10 |只看该作者
下面我们来解压 UDEV 软件包,同时将 udev-config 解压到 udev 软件包得源码目录下。

我们首先需要创建一些 udev 无法创建的设备文件和目录。

install -dv /lib/{firmware,udev/devices/{pts,shm}}
mknod -m 0666 /lib/udev/devices/null c 1 3
ln -sv /proc/self/fd /lib/udev/devices/fd
ln -sv /proc/self/fd/0 /lib/udev/devices/stdin
ln -sv /proc/self/fd/1 /lib/udev/devices/stdout
ln -sv /proc/self/fd/2 /lib/udev/devices/stderr
ln -sv /proc/kcore /lib/udev/devices/core

创建完成以后,我们需要开始编译并安装 udev
编译参数如下:
make DESTDIR=/ \
EXTRAS="extras/ata_id extras/cdrom_id extras/edd_id extras/firmware extras/floppy extras/path_id extras/scsi_id extras/usb_id extras/volume_id"

这里面我们要特别注意 DESTDIR=/ 参数,它可以防止编译 Udev 的进程杀死可能存在于宿主系统中的 udevd 进程。

udev 要工作,需要进行配置,我们先创建 /etc/udev/rules.d/ 目录,然后执行如下语句。

cp -v udev-config-6.2/[0-9]* /etc/udev/rules.d/

安装好了吗?

下面我们来开始编译网络程序  Inetutils、IPRoute2-2.6.16-060323 。
这两个程序没有什么特殊的,需要注意采用静态编译的方式进行安装。
我们先给 inetutils 打上补丁。
进入 inetutils 目录,运行 patch -Np1 -i ../inetutils-1.4.2-gcc4_fixes-3.patch

配置编译环境 。
./configure --prefix=/usr --libexecdir=/usr/sbin \
--sysconfdir=/etc --localstatedir=/var \
--disable-logger --disable-syslogd \
--disable-whois --disable-servers

然后执行 make LDFLAGS="-static" & make install

安装 IPRoute2 , 直接编译。
make SBINDIR=/sbin install
编译安装完成后,我们将 arpd 移动到 /uysr/sbin 目录之下。
# mv /sbin/arpd /usr/sbin

下面我们开始安装键盘映射 kbd 和配置文件查找程序 。

先打上补丁。
patch -Np1 -i ../kbd-1.12-backspace-1.patch
patch -Np1 -i ../kbd-1.12-gcc4_fixes-1.patch

配置编译环境。
./configure --datadir=/lib/kbd

# make & make install
移动我们生成的文件到根目录(这是因为在某些情况下,我们的配置文件会在根目录下的 /bin 目录下查找,而不会到 /usr/bin 下面去查找,比如说你进入维护模式的时候。
# mv -v /usr/bin/{kbd_mode,openvt,setfont} /bin

安装 less 环境参数查找程序。
配置编译环境。
./configure --prefix=/usr --sysconfdir=/etc
编译并安装
# make & make install

安装 安装 Module-Init-Tools 软件包。
我们先给安装 Module-Init-Tools打上补丁:
patch -Np1 -i ../module-init-tools-3.2.2-modprobe-1.patch

清理源码树
./configure &&
make check &&
make distclean

配置编译环境
./configure --prefix=/ --enable-zlib
强制编译并安装
# make INSTALL=install install

安装启动脚本文件 安装 LFS-Bootscripts
# make install
这个启动脚本文件的简单说明如下:
checkfs
在挂载之前检查文件系统完整性(日志文件系统和基于网络的文件系统除外)
cleanfs
删除系统重启后就不需要保存了的文件,例如在 /var/run/ 和 /var/lock/ 目录下的文件;重新创建 /var/run/utmp 文件并删除可能存在的 /etc/nologin, /fastboot, /forcefsck 文件。
console
为指定的键盘布局读入正确的键盘映射表,并设置屏幕字体。
functions
包含在不同脚本中共用的一些函数,例如错误和状态检查函数。
halt
关闭系统
hotplug
为系统设备加载模块
ifdown
协助 network 脚本停止网络设备
ifup
协助 network 脚本启动网络设备
localnet
设置系统主机名和本地回环(loopback)设备
mountfs
挂载所有文件系统,有 noauto 标记或者基于网络的文件系统除外。
mountkernfs
用来挂载内核提供的文件系统,例如 proc
network
设置网络连接,例如网卡等;并设置默认网关(如果可用) 。
rc
主要的运行级控制脚本,负责让所有其它脚本按符号链接名确定的顺序一个接一个的运行。
reboot
重新启动系统
sendsignals
在系统重启或关闭系统之前,确保每一个进程都已经终止了。
setclock
如果硬件时钟没有设置为 UTC 时间,将内核时钟重置为本地时间。
static
提供为网络接口指派静态 IP 地址的功能
swap
启用或禁用交换文件和交换分区
sysklogd
启动或停止系统和内核日志守护进程
template
为其它守护进程创建自定义启动脚本的模板
udev
启动 udev 并在 /dev 目录创建设备节点

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
48 [报告]
发表于 2012-04-15 23:14 |只看该作者
下面我们来开始配置启动脚本和设备加载文件。

以下内容,我们使用 vim 编辑器来进行编写(vim 不会使用的请 google 或者在本论坛内进行搜索。)
文件 /etc/sysconfig/clock
  1. # Begin /etc/sysconfig/clock
  2. UTC=0
  3. # End /etc/sysconfig/clock
复制代码
文件 /etc/sysconfig/console
这个文件我没有修改,甚至这个文件我都没有建立,因为我们的系统就是使用的英文的,这是系统的默认设置。

文件 /etc/inputrc
  1. # Modified by Chris Lynn <roryo@roryo.dynup.net>
  2. # Allow the command prompt to wrap to the next line
  3. set horizontal-scroll-mode Off
  4. # Enable 8bit input
  5. set meta-flag On
  6. set input-meta On
  7. # Turns off 8th bit stripping
  8. set convert-meta Off
  9. # Keep the 8th bit for display
  10. set output-meta On
  11. # none, visible or audible
  12. set bell-style none
  13. # All of the following map the escape sequence of the
  14. # value contained inside the 1st argument to the
  15. # readline specific functions
  16. "\eOd": backward-word
  17. "\eOc": forward-word
  18. # for linux console
  19. "\e[1~": beginning-of-line
  20. "\e[4~": end-of-line
  21. "\e[5~": beginning-of-history
  22. "\e[6~": end-of-history
  23. "\e[3~": delete-char
  24. "\e[2~": quoted-insert
  25. # for xterm
  26. "\eOH": beginning-of-line
  27. "\eOF": end-of-line
  28. # for Konsole
  29. "\e[H": beginning-of-line
  30. "\e[F": end-of-line
复制代码
文件 /etc/bashrc
  1. # /etc/bashrc

  2. # System wide functions and aliases
  3. # Environment stuff goes in /etc/profile

  4. # by default, we want this to get set.
  5. # Even for non-interactive, non-login shells.
  6. if [ "`id -gn`" = "`id -un`" -a `id -u` -gt 99 ]; then
  7.     umask 002
  8. else
  9.     umask 022
  10. fi

  11. # are we an interactive shell?
  12. if [ "$PS1" ]; then
  13.     case $TERM in
  14.     xterm*)
  15.         if [ -e /etc/sysconfig/bash-prompt-xterm ]; then
  16.             PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm
  17.         else
  18.             PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
  19.         fi
  20.         ;;
  21.     screen)
  22.         if [ -e /etc/sysconfig/bash-prompt-screen ]; then
  23.             PROMPT_COMMAND=/etc/sysconfig/bash-prompt-screen
  24.         else
  25.         PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\033\\"'
  26.         fi
  27.         ;;
  28.     *)
  29.         [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=/etc/sysconfig/bash-prompt-default
  30.         ;;
  31.     esac
  32.     # Turn on checkwinsize
  33.     shopt -s checkwinsize
  34.     [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
  35. fi

  36. if ! shopt -q login_shell ; then # We're not a login shell
  37.         for i in /etc/profile.d/*.sh; do
  38.         if [ -r "$i" ]; then
  39.             . $i
  40.         fi
  41.     done
  42.     unset i
  43. fi
  44. # vim:ts=4:sw=4
复制代码
文件 /root/.bashrc
  1. # .bashrc

  2. # User specific aliases and functions

  3. # Source global definitions
  4. if [ -f /etc/bashrc ]; then
  5.         . /etc/bashrc
  6. fi
复制代码
文件 /etc/.bash_profile
  1. # .bash_profile

  2. # Get the aliases and functions
  3. if [ -f ~/.bashrc ]; then
  4.         . ~/.bashrc
  5. fi

  6. # User specific environment and startup programs

  7. PATH=$PATH:$HOME/bin

  8. export PATH
  9. unset USERNAME
复制代码
文件 /etc/sysconfig/network
  1. HOSTNAME=My_Operation
复制代码
文件 /etc/hosts
  1. # Do not remove the following line, or various programs
  2. # that require network functionality will fail.
  3. 127.0.0.1               localhost.localdomain localhost
复制代码
创建 cd-rom ( dvd-rom ) 的自动挂载连接
文件 /etc/udev/rules.d/82-cdrom.rules
  1. # Custom CD-ROM symlinks
  2. SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", ENV{ID_PATH}=="pci-0000:00:07.1-ide-0:1", SYMLINK+="cdrom"
  3. SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", ENV{ID_PATH}=="pci-0000:00:07.1-ide-1:1", SYMLINK+="cdrom1 dvd"
复制代码
创建随机设备符号连接规则文件。
文件 /etc/udev/rules.d/83-duplicate_devs.rules
  1. KERNEL=="video*", SYSFS{idProduct}=="1910", SYSFS{idVendor}=="0d81", SYMLINK+="webcam"
  2. KERNEL=="video*", SYSFS{device}=="0x036f", SYSFS{vendor}=="0x109e", SYMLINK+="tvtuner"
复制代码
创建网络设备符号连接规则文件
文件 /etc/udev/rules.d/26-network.rules
  1. ACTION=="add", SUBSYSTEM=="net", SYSFS{address}=="00:e0:4c:12:34:56", NAME="realtek"
  2. ACTION=="add", SUBSYSTEM=="net", SYSFS{address}=="00:a0:c9:78:9a:bc", NAME="intel"
复制代码
注意:这里面的 00:e0:4c:12:34:56 是网卡的 MAC 值,可以通过 grep -H . /sys/class/net/*/address 来获得。

创建网络接口配置文件 /etc/sysconfig/network-devices/ifconfig.eth0/ipv4
  1. ONBOOT=yes SERVICE=ipv4-static IP=192.168.1.1 GATEWAY=192.168.1.2 PREFIX=24 BROADCAST=192.168.1.255
复制代码
创建网络接口DNS域名解析文件 /etc/resolv.conf
  1. domain {<域名>} nameserver <主域名服务器IP地址>
  2. nameserver <副域名服务器IP地址>
复制代码
配置设备自动挂载文件 /etc/fstab
  1. /dev/hda1 /boot ext3 defaults 1 1
  2. /dev/hda2 swap swap pri=1 0 0
  3. /dev/hda3 / ext3 defaults 1 1
  4. proc /proc proc defaults 0 0
  5. sysfs /sys sysfs defaults 0 0
  6. devpts /dev/pts devpts gid=4,mode=620 0 0
  7. shm /dev/shm tmpfs defaults 0 0
复制代码
创建 /boot 和 /swap 目录,以便我们的系统启动时进行挂载。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
49 [报告]
发表于 2012-04-15 23:49 |只看该作者
本帖最后由 snow888 于 2012-04-16 02:00 编辑

下面我们创建两个与系统用户有关的配置文件 /etc/passwd 和 /etc/group

这两个文件我们就不要手写了,直接拷贝母体的文件,然后将无用的信息删除即可。

下面我们开始安装 grub 和 linux 内核 。

安装 grub ,我们需要先打上补丁。
patch -Np1 -i ../grub-0.97-disk_geometry-1.patch
配置编译选项:
./configure --prefix=/usr
安装
make & make install

这里我们来停一下,还记得我们的这个物理磁盘(或者是 U 盘)是如何分区的么?
对 /dev/sdb1   /boot
/dev/sdb2       /swap
/dev/sdb3       /
我们的系统现在在 /dev/sdb3 上,我们需要将 /boot 挂载上来。
mount /dev/sdb1 /boot                   ;; 如果 /boot 目录没有,我们要先创建。

然后我们来执行如下的 copy 命令
mkdir -v /boot/grub
cp -v /usr/lib/grub/i386-pc/stage{1,2} /boot/grub

如果你的不是 i386 平台,你需要根据自己的实际环境来做相应的拷贝。

下面我们来安装 linux 内核,和前面一样,我们还是要先打上补丁。
patch -Np1 -i ../linux-2.6.16.27-utf8_input-1.patch

执行下面的命令来准备编译
make mrproper
这样做得目的是检查源码树,保证我们的内核源码绝对干净。

make menuconfig
以菜单方式配置内核选项,相信编译过内核的朋友,比我肯定熟悉多了。 ^_^.

编译内核镜像和模块:
make

安装模块,如果内核配置使用它们:
make modules_install

拷贝启动镜像到 /boot 目录。
cp -v arch/i386/boot/bzImage /boot/kernel-2.6.16.27
cp -v System.map /boot/System.map-2.6.16.27
cp -v .config /boot/config-2.6.16.27

安装 grub 引导到硬盘
# grub
grub> root (hd0,2)
grub> setup(hd0)
grub>exit
#
编写系统引导菜单 文件 /boot/grub/menu.lst。
  1. # By default boot the first menu entry.
  2. default 0
  3. # Allow 30 seconds before booting the default.
  4. timeout 30
  5. # Use prettier colors.
  6. color green/black light-green/black
  7. # The first entry is for My_Operation.
  8. title My_Operation 6.2
  9. root (hd0,2)
  10. kernel /boot/kernel-2.6.16.27 root=/dev/hda3
复制代码
特别注意:我们的硬盘编号和分区编号是从 0 开始的,即第一块硬盘的编号是 hd0 , 第一个分区的编号是 0 号。
在 /etc/grub 下创建一个启动链接。
mkdir -v /etc/grub &&
ln -sv /boot/grub/menu.lst /etc/grub

这一步非必须,但是我们强烈建议你这样做。

好了,我们现在退出新的系统,回到宿主机。
# exit

卸载新的系统
# umount /dev/sdb1
# umount /dev/sdb3

重新启动,进入 cmos 将宿主机的硬盘 disable,然后再重新启动,让你的新系统运行起来。
怎么样,出现了 login: 了么。 ^_^.

到这里,我们已经完成了从 0 开始打造自己的 linux 的全部过程,下一步,如果你需要安装图形界面,可以自己在这个新的系统上编译安装了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
50 [报告]
发表于 2012-04-16 00:18 |只看该作者
本帖最后由 snow888 于 2012-04-16 02:04 编辑

晕乎乎,这系统终于出来了。

最后的总结。


系统实现的主要思想及流程:

从宿主机编译一个基本脱离母体系统的开发工具链 ——>利用这个工具链编译安装最初的基本命令——>利用这个工具链编译出完全脱离母体开发环境的新生系统的工具链——>挂载虚拟文件系统——>切换 shell 到新生系统上,并将根目录替换成我们自己的目录——>在新生系统上用二次编译的开发工具编译安装系统的核心文件系统和命令程序——>配置启动参数文件——>挂载 /boot 区并安装 grub 和 linux 内核 ——> 脱离母体并利用新生系统引导。



系统打造过程中需要注意的事项:
1、系统的命令部分,尽量以静态编译的方式来生成。避免进入新生系统后,由于 libgcc_s.so.2 等动态链接库的相对位置移动而造成命令无法使用的情况,尤其是二次编译 gcc 和 binutils 的时候,应注意让生成的命令全部是静态编译的方式实现的。
2、合理组织自己的文件系统,比如我的编译过程中,gcc 安装到了 / 根目录,这是极其不合理的,兄弟们在二次编译 gcc 和 binutils 的时候,安装目录应指向 /My_Operation/myuser/usr 目录,切记!切记!
3、除设置系统基本特征的工具Coreutils和系统的基本命令 Util-linux 安装到 /My_Operation/myuser/ 以外,其余部分我们建议安装到 /My_Operation/myuser/usr 。



本文与 lfs 中相同和不一样的地方。
1、本文的二次编译开发工具链的目的及方法与 lfs 略有不同,同时本文大部分的新生系统的命令在宿主机上编译完成,避免了新系统上开发包不完整造成的命令编译安装失败。
2、本文的启动参数配置与 lfs 基本一样,事实上,几乎所有的自己打造系统都逃不出这样的模式,这也是 lfs 一文最为难能可贵之处。
3、构建过程中,部分编译参数与 lfs 不同,可能是考虑的角度不一样吧,究竟哪种编译参数优劣,朋友们可以自己去体会。


最后,我们来回顾一下操作系统的演化过程。

最早的计算器是什么——算盘。
最早的程序语言是什么——我们一起来:一上一、二上二、三下五去二、四去六进一 ... ..

这些东西也许大家忘记了,我们一起来回忆。

最早的机械计算器是一台带有 1千多个齿轮的大机器,后来发展到了电子管的计算器,从此出现了打孔编程,再后来,由于计算的结果不能保存,不能被重复利用,每次进行关联计算都需要将上次的计算结果输入一遍然后再计算,这就出现了外部的存储,最早是 4KB , 后来到 64KB ,再后来到了 1MB ,这个时候出现了能实现不同计算用途的需求,于是人们开始考虑将系统的接口部分独立出来,做一个中间层来进行翻译,这个中间层就是最早的操作系统雏形。

这个雏形最开始是用 0 、1 输入的,纯机器码组成。后来进行了扩展,为了解决用 0 和 1 编程的问题,出现了一种简单的机器描叙语言——汇编,然后有人用汇编重写了计算机的软件和硬件的接口部分,形成了早期的能与特定机器绑定的操作系统,最早的苹果、王安电脑等。

再到后来,在汇编语言发展的同时,出现了新的更为简洁的语言,如 B 语言等。

再后来,AT&T 公司的两位天才,用汇编重写了 C 语言,并用 C 语言编写了第一套能脱离具体硬件环境的操作系统 ——Unix 。

到这里,我们的真正意义上的操作系统就诞生了。

今天,我们已经不需要用 0,1 先写一个汇编语言出来,然后再用汇编写一个 C 语言出来,再用 C 语言开发一套操作系统出来了,我们已经有了很好的工具链,我们需要做的就是用这个工具链来开发系统(事实上,这个系统都有人替我们写好了,我们只是自己编译安装了一下而已)。

严格意义上来说,这个过程并非是真正意义上的从 0 开始,打造我们自己的 linux 系统。

最后,祝朋友们顺利打造出属于自己的 linux 系统。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP