下面将介绍如何建立绕回设备
要建立一个绕回根目录设备必须要有下列事项.
最重要的是必须能存取一个安装好可运作的 Linux 系统. 这是因为绕回设备只能在 Linux 下建立. 也就是说你不可能从无中生有. 而且你必须要能在这个系统上编译核心.
当绕回设备建立之後, 这将是一个很大的档案. 我使用了一个 80 MB 的档案, 如此我才能建立一个 X 终端机; 但如果你希望能做更多事, 这可能也不够. 这个档案必须被复制到 DOS 分割区中, 所以网路或是一堆软碟是必须的.
你所需要的软体包括:
LOADLIN
1.6版以上mount
程式对现在的 Linux 而言, 应该都能符合以上需求.
我是用 2.0.31 版的核心来使用绕回装置, 其他版本的核心应该也可以用. 但他们至少必须要有以下的功能.
你必须将核心的列功能启动
CONFIG_BLK_DEV_RAM
).CONFIG_BLK_DEV_INITRD
).CONFIG_BLK_DEV_LOOP
).CONFIG_FAT_FS
).CONFIG_MSDOS_FS
).前面二个是用来使用记忆体磁碟装置与初始化记忆体磁碟装置. 第三个是绕回档案系统的支援, 最後二个则是用来挂载 DOS 分割区所必须的支援.
编译核心且不使用模组支援是最简单的选择. 但如果你希望使用模组化支援应该也是可以, 虽然我没有试过. 如果你使用模组化支援, 你必须确定上列的选项是直接编译在核心内而不是编译成模组.
依据核心版本的不同, 你可能需要使用一些修补. 下面是一些简单的修补用来让核心可以将绕回装置作为根目录档案系统使用.
对於 2.0.x 版的核心, 必须将 "loop", 0x0700
这一行加到 /init/main.c
的原始码中而成为下面的样子.
static void parse_root_dev(char * line)
{
int base = 0;
static struct dev_name_struct {
const char *name;
const int num;
} devices[] = {
{ "nfs", 0x00ff },
{ "loop", 0x0700 },
{ "hda", 0x0300 },
...
{ "sonycd", 0x1800 },
{ NULL, 0 }
};
...
}
对於 2.2.x 版的核心, 必须将 "loop", 0x0700
与前後各一行(共三行)加到 /init/main.c
的原始码中而成为下面的样子
static struct dev_name_struct {
const char *name;
const int num;
} root_dev_names[] __initdata = {
#ifdef CONFIG_ROOT_NFS
{ "nfs", 0x00ff },
#endif
#ifdef CONFIG_BLK_DEV_LOOP
{ "loop", 0x0700 },
#endif
#ifdef CONFIG_BLK_DEV_IDE
{ "hda", 0x0300 },
...
{ "ddv", DDV_MAJOR << 8},
#endif
{ NULL, 0 }
};
当核心组态设好後, 他必须被编译成 zImage
档 (make zImage
).
编译好的档案会被放在 arch/i386/boot/zImage
.
建立初始化记忆体磁碟最简单的方式是将它当成绕回装置挂载.
你必须使用 root 的权限来做这件事.
建立程序如下所示, 这些指令是在 root 的家目录 (/root
) 中执行的.
mkdir /root/initrd
dd if=/dev/zero of=initrd.img bs=1k count=1024
mke2fs -i 1024 -b 1024 -m 5 -F -v initrd.img
mount initrd.img /root/initrd -t ext2 -o loop
cd initrd
[建立必须的档案]
cd ..
umount /root/initrd
gzip -c -9 initrd.img > initrdgz.img
这些指令的作用如下所述.
初始化记忆体磁碟的内容
你必须至少有下列的档案放置於初始化记忆体磁碟中, 否则将不能使用任何指令.
/linuxrc
挂载 DOS 档案系统的指令稿. (如下所示)/lib/*
程式所需要的动态连结器与函式库./etc/*
动态连结所需的快取, 虽然静态连结程式不需要, 但可以避免警告讯息./bin/*
使用者命令解译器 (此处我使用 ash
, 因为它比 bash
小).
而 mount
与 losetup
程式是用於挂载 DOS 磁碟与设定绕回装置./dev/*
必须的装置控制档, 你至少需要 /dev/zero
以供 ld-linux.so
使用, /dev/hda*
以挂载 DOS 磁碟, 以及 /dev/loop*
以挂载绕回装置./mnt
一个空的挂载点, 以供 DOS 磁碟挂载.下面是我所用的起始化记忆体磁碟之内容, 所需空间约 800 kB.
total 18
drwxr-xr-x 2 root root 1024 Jun 2 13:57 bin
drwxr-xr-x 2 root root 1024 Jun 2 13:47 dev
drwxr-xr-x 2 root root 1024 May 20 07:43 etc
drwxr-xr-x 2 root root 1024 May 27 07:57 lib
-rwxr-xr-x 1 root root 964 Jun 3 08:47 linuxrc
drwxr-xr-x 2 root root 12288 May 27 08:08 lost+found
drwxr-xr-x 2 root root 1024 Jun 2 14:16 mnt
./bin:
total 168
-rwxr-xr-x 1 root root 60880 May 27 07:56 ash
-rwxr-xr-x 1 root root 5484 May 27 07:56 losetup
-rwsr-xr-x 1 root root 28216 May 27 07:56 mount
lrwxrwxrwx 1 root root 3 May 27 08:08 sh -> ash
./dev:
total 0
brw-r--r-- 1 root root 3, 0 May 20 07:43 hda
brw-r--r-- 1 root root 3, 1 May 20 07:43 hda1
brw-r--r-- 1 root root 3, 2 Jun 2 13:46 hda2
brw-r--r-- 1 root root 3, 3 Jun 2 13:46 hda3
brw-r--r-- 1 root root 7, 0 May 20 07:43 loop0
brw-r--r-- 1 root root 7, 1 Jun 2 13:47 loop1
crw-r--r-- 1 root root 1, 3 May 20 07:42 null
crw-r--r-- 1 root root 5, 0 May 20 07:43 tty
crw-r--r-- 1 root root 4, 1 May 20 07:43 tty1
crw-r--r-- 1 root root 1, 5 May 20 07:42 zero
./etc:
total 3
-rw-r--r-- 1 root root 2539 May 20 07:43 ld.so.cache
./lib:
total 649
lrwxrwxrwx 1 root root 18 May 27 08:08 ld-linux.so.1 -> ld-linux.so.1.7.14
-rwxr-xr-x 1 root root 21367 May 20 07:44 ld-linux.so.1.7.14
lrwxrwxrwx 1 root root 14 May 27 08:08 libc.so.5 -> libc.so.5.3.12
-rwxr-xr-x 1 root root 583795 May 20 07:44 libc.so.5.3.12
./lost+found:
total 0
./mnt:
total 0
比较复杂的步骤是建立 dev
目录下面的装置控制档.
你可以用 /dev
下面现有的装置控制档为□本, 并以 mknod
程式来建立他们.
/linuxrc 指令档
起始化记忆磁碟中的 /linuxrc
指令稿是用来完成挂载绕回装置所需的前置准备.
下面的□例是以 /dev/hda1
为 DOS 分割区, 并在成功挂载 DOS 分割区後, 将/linux/linuxdsk.img
设定为 /dev/loop0
;并将 /linux/linuxswp.img
设定为 /dev/loop1
.
#!/bin/sh
echo INITRD: Trying to mount /dev/hda1 as msdos
if /bin/mount -n -t msdos /dev/hda1 /mnt; then
echo INITRD: Mounted OK
/bin/losetup /dev/loop0 /mnt/linux/linuxdsk.img
/bin/losetup /dev/loop1 /mnt/linux/linuxswp.img
exit 0
else
echo INITRD: Mount failed
exit 1
fi
前面的 /dev/loop0
装置将被挂载为根目录, 後面的 /dev/loop1
则将被作为记忆体置换区使用.
如果你希望 root 以外的使用者也能写入 DOS 分颗区, 你必须改成使用 mount -n -t msdos /dev/hda1 /mnt -o uid=0,gid=0,umask=000,quiet
.
这会将所有对 DOS 分割区的存取对应成 root, 并且适当的设定权限.
你所使用的根目录装置将是 linuxdsk.img
这个档案.
你可以用与建立起始记忆体磁碟相同的方法建立这个档案, 所不同处仅在於必须较大, 足以容纳你要安装的程式.
最简单的办法是将现有的 Linux 系统复制到这个档案系统中. 当然你也可以重新安装一套新的 Linux 系统.
假设你已经做过这些事, 你只要作一些小改变.
/etc/fstab
档案必须将根目录磁碟与置换区对应到你在启示记忆体磁碟中的绕回设备.
/dev/loop0 / ext2 defaults 1 1
/dev/loop1 swap swap defaults 1 1
这将确保核心会使用正确的根目录装置. 也可以用相同的方法加入置换磁碟. 你也必须移除其他根目录磁碟与置换区的对应.
如果你希望在 Linux 启动後能够读取 DOS 分割区, 你必须作下面这些额外的小修改.
建立叫做 /initrd
的目录, 这是再绕回根目录系统挂载後, 初始记忆体磁碟挂载的地方.
建立一个符号连接 /DOS
指向 /initrd/mnt
, 也就是 DOS 分割区被挂载的地方.
在 rc 档中加入类似 mount -f -t msdos /dev/hda1 /initrd/mnt
的指令, 以建立一个 "假的" 挂载, 如此例如 df
等程式才会知道这个挂载.
如果你在 /linuxrc
中用不同的设定, 请自行修正以符合设定.
由於核心在之前便会被载入, 所以你不需要在根目录装置中放置系统核心. 但如果你使用了核心的模组, 你仍然必须将这些模组放在根目录装置中.
你所使用的置换装置将是 linuxswap.img
.
这个置换装置相当容易建立.
首先如同之前的做法建立一个空档案, 然後执行 mkswap linuxswap.img
来格式化这个置换档.
置换空间的大小依据个人的使用而不同, 但我建议将它设为大於 8MB, 但小於实体记忆体量.
你所要使用的档案必须被搬移到 DOS 分割区中.
必须被放在 C:\LINUX
目录下的档案包括
LINUXDSK.IMG
作为根目录装置的影像档.LINUXSWP.IMG
置换装置.
开机软碟的制作与标准 DOS 开机软碟相同.
在 DOS 下使用 format a: /s
以建立开机软碟.
在这张软碟上, 你必须建立一个 AUTOEXEC.BAT
档, 如下所示.
并且复制 Linux 系统核心与压缩过的起始记忆体磁碟档案, 以及 LOADLIN
执行档.
AUTOEXEC.BAT
- DOS 下的开机自动执行批次档.LOADLIN.EXE
- LOADLIN
执行档.ZIMAGE
- Linux 系统核心.INITRDGZ.IMG
- 压缩过的起始记忆体磁碟档.AUTOEXEC.BAT
仅需要下面这行.
\loadlin \zImage initrd=\initrdgz.img root=/dev/loop0 ro
这会指定要用的系统核心与起始化记忆体磁碟档以及根目录磁碟的位置, 并将根目录以唯读的方式挂载.