您的位置:首页 > 运维架构 > Shell

关于用Grub制作启动光盘的知识.

2007-07-19 09:47 309 查看
下面的内容可能有帮助
后附 knoppix 的 linuxrc 可供参考
主要是linuxrc这个

LiveCD的制作
经过几天的研究,写了几页豆腐,如今也来这里酸一酸,因为贴图不太方便,所以只在这里摘录前面一截,感兴趣的朋友可以下载附件中的pdf文档观看,谢谢.

另外,在这里下PDF版本:

http://mypretty.nease.net/livecd/LiveCD_Study.pdf

看的会舒服点,呵呵.

前言—为什么要写这篇文档.
整整三天的时间,为了搞清楚linux的启动机制,回过头来看看,一切似乎非常的简单. 可是当这样的事情要由一个人独立的没有任何基础的去研究的时候,就会走很多的弯路.经过这充实的三天,我知道了一些原先不知道或者不清楚的事,我对linux系统的认识又清晰的许多.
现在,假定你还不知道我已经知道的那些,你不必象我一样,通过Google和反复的修改脚本,反复的制作光盘,反复的重启来搞清楚这些,你只需要读我写的这篇文档. 按照文中所说的步骤(这些步骤非常的清晰,所使用的东西也随手可得),你便可以很快的回答以下这些问题:
关于用Grub制作启动光盘的知识.
关于制作Initrd的知识.
制作一个什么都不能做的LiveCD.
其它的一些我有提到但是忘记了写在这里的知识.
如果你喜欢Linux,如果你觉得这篇文档能让你知道了一些你以前不知道并且想知道的,或者仅仅是因为个人感情的原因对作者投以支持的目光,作者便会觉得如坐春风了,这就是写这篇文档的目的.
当然,作者是从一无所知到现在的略有所知,所以肯定会有理解偏颇甚至错误的地方,在大方那里难免被贻笑,也请大家鸡蛋不要仍的太多,但是绝对欢迎批评指正,免的误导更多的人,小弟的罪过就大了.
好了,废话说太多了,赶紧启动你的FedoraCore3吧.
制作Grub启动光盘
LiveCD首先是一个可以自启动的光盘,通常现有的LivdCD使用的都是ISOLinux1 的技术,其实使用Grub也可以制作可以启动的光盘.以下片断参考自Grub的Info文档:
$ mkdir iso # 新建一个iso目录,这将作为LiveCD的镜像目录.
$ mkdir -p iso/boot/grub #在iso目录中创建boot/grub子目录,这其实和你的FedoraCore3的/boot结构是一样的.
$ cp /usr/share/grub/i386-redhat/stage2_eltorito iso/boot/grub #i386-redhat这个目录名字可能不同.2
$ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot /
-boot-load-size 4 -boot-info-table -o teach.iso iso #制作以iso目录为镜像目录的启动光盘.3
现在生成了teach.iso文件,打开Vmware,新建一个linux虚拟机,将光盘指定成新生成的teach.iso,如下图所示:
启动这个VirtualMachine, 在系统自检的时候摁F2进入Bios,修改成从光盘启动
,如下图所示
摁F10存盘退出后重新启动, 启动结果如下图所示:
系统已经启动到grub提示符的状态, 这时候我们可以输入后续grub命令来启动系统.

Ok,让我们重新回到FedoraCore3, 拷贝我们需要的文件到iso,以便我们的LiveCD可以走的更远:
$cp /boot/vmlinuz-2.6.9-1.667 iso/boot/ #拷贝系统内核到iso的boot目录
$ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot /
-boot-load-size 4 -boot-info-table -o teach.iso iso #重新生成我们的iso文件

现在重新启动我们的VirtualMachine,在Grub提示符下依次敲入如下命令:
grub> root (cd)
grub> kernel /boot/vmlinuz-2.6.9-1.667
grub> boot
如下图所示:
没错,我们的liveCD又往前走了很多,可以看到kernel被启动,很多的提示信息,不过在kernel启动的最后,出现了错误:
这是因为kernel启动到最后,找不到init程序,也找不到root文件系统导致.接下来,我们要制作 initrd.img这个虚拟镜像文件了.

在制作initrd.img之前,我们不妨先在iso/boot/grub目录下创建一个grub.conf(按照grub的手册,这个文件好像应该叫做menu.lst)文件,以避免我们每次重新启动liveCD的时候都要输出一堆grub命令. 参考/boot/grub/grub.conf.
grub.conf 的文件内容可以如下所示(As your wish):
#grub.conf start *********************************
default 0
timeout 1
hiddenmenu
title LiLiHome
root (cd)
kernel /boot/vmlinuz-2.6.9-1.667 quiet
#grub.conf end *********************************
这个文件告诉grub,启动的时候默认启动第一个title, 等待时间是1秒钟,不要显示选择菜单,第一个Title的名字是LiLiHome(^_^,as your wish),依次执行的命令是 root ...和kernel ...,其中quiet参数告诉kernel启动的时候不要显示那一堆无所谓的信息,我只是个初级的fans,对这些输出并不关心.
重新制作我们的iso文件,不会再出现grub提示符,而是直接启动指定的kernel了.

我们以后还会回来修改grub.conf的,现在,让我们先来做initrd.img吧.

制作Initrd.img
为什么要制作initrd,img? 我们的这个initrd.img要完成什么功能?
Initrd可以让kernel分成两个步骤启动,第一个步骤加载一个比较小的kernel,其中可能不包括在编译kernel的时候编译成module的那些模块,第二个步骤中可以加载这些模块并且完成一些最小系统的初始化.Linux的文档是这么说的.不过我们的initrd只是帮我们完成一个小任务,找到光盘.
以下的这些操作中的一部分需要你拥有root权限,所以,现在我们最好su一把,让我们自己变成root.
$ su #输入密码,变成root(牛气的root)
# mkdir initrd #创建一个initrd的目录,我们会把initrd.img挂载到这个目录
# dd if=/dev/zero of=initrd.img bs=400k count=10 #创建一个4M的initrd.img
# /sbin/mke2fs -F -m0 initrd.img # 将initrd.img初始化成ex2文件系统
# mount -o loop initrd.img initrd # 将initrd.img挂载到initrd上
# mkdir initrd/dev #在initrd目录(也就是initrd.img文件)中创建/dev目录
# mknod initrd/dev/console c 5 1 # 增加一个控制台节点1. 事实上,需要.

initrd作为kenerl的出口,可以是一个普通的ex2文件系统的压缩文件(并非一定如此),kernel会寻找initrd中的linuxrc文件(这个文件一定要是可以执行的,可以是shell脚本),然后执行它.

下面的工作,我们会增加initrd.img的核心部分,不过不要着急,在这之前让我们先修改我们的grub.conf2文件,增加需要的内容,按照linux文件,如果要使用initrd.img,grub.conf应该这样修改:
grub.conf 的文件内容可以如下所示(As your wish):
#grub.conf start *********************************
default 0
timeout 1
hiddenmenu
title LiLiHome
root (cd)
kernel /boot/vmlinuz quiet root=/dev/ram0 rw init=/linuxrc
initrd /boot/initrd.img
#grub.conf end *********************************
这其中除了quiet参数你可以随便以外,别的最好不要修改,尽管有些参数不是必须的.
好了,我们来往initrd.img里面增加内容吧:
# mkdir initrd/bin # 增加bin目录
# cp /bin/bash initrd/bin/ #要运行脚本,当然需要bash(任何一个shell包括busybox3都可以)
# ldd /bin/bash #看看我们的bash需要哪些动态链接库
libtermcap.so.2 => /lib/libtermcap.so.2 (0x005b1000)
libdl.so.2 => /lib/libdl.so.2 (0x004c0000)
libc.so.6 => /lib/tls/libc.so.6 (0x00372000)
/lib/ld-linux.so.2 (0x00359000)
# mkdir initrd/lib #看来我们需要lib目录了
# ls -l /lib/libtermcap.so.2 #看看我们需要的第一个动态链接库是不是个链接
lrwxrwxrwx 1 root root 24 12? 9 14:10 /lib/libtermcap.so.2 -> /lib/libtermcap.so.2.0.8
# cp /lib/libtermcap.so.2.0.8 initrd/lib/ #果然是个链接,要拷贝真正的文件而不是一个符号哦.
# cd initrd/lib
# ln -s libtermcap.so.2.0.8 libtermcap.so.2 #当然符号还是要建的.
...... # 依次操作后面的几个库吧.

好,假定你读到这里的时候,所有需要的库已经拷贝到lib目录了,我们需要检验一下新的bash能不能够运行.
# /usr/sbin/chroot initrd bash #试着执行一下拷贝过去的bash,注意要chroot
bash-3.00# #出现了提示符,说明需要的库我们都拷贝全了.
bash-3.00# exit #退回到原来的提示符下
# cd initrd/bin # 去initrd的bin目录
# ln -s bash sh # 建立 sh符号链接到bash.
好了,我们来测试一下我们的initrd.img. 退回到initrd的上一级目录.
# vi initrd/linuxrc #我们来建立一个linuxrc
#!/bin/sh
echo 'Hellow World!'
sh
# chmod a+x initrd/linuxrc #给予linuxrc可执行属性
# cp /bin/echo initrd/bin/ #既然我们的linuxrc中用到了echo,那么拷贝吧
# ldd /bin/echo #看看echo需要的库我们都有吗?
libc.so.6 => /lib/tls/libc.so.6 (0x00372000)
/lib/ld-linux.so.2 (0x00359000)
...... #如果有我们没有的,拷贝之.

好了现在我们的initrd已经不是一个空空的文件了.我们试一下它可不可以执行.
先确定你的grub.conf已经修改.然后
# umount initrd #确保
# cp initrd.img iso/boot/
# gzip -9 iso/boot/initrd.img
# mv iso/boot/initrd.img.gz iso/boot/initrd.img
# mkisofs -R -b boot/grub/stage2_e 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息