恩恩,本周的实验看起来不难,下面是实验要求:

实验内容:

  1. 制作启动硬盘并启动一个操作系统映像
  2. 下载 grub-0.97.tar.gz 并编译,或者直接下载 grub-0.97-i386-pc.tar.gz(这是已经编译好的)
  3. 制作grub启动软盘,进而制作启动硬盘
  4. 操作系统映像:可以到网络上下载一个可用的OS映像,然后编写menu.lst或grub.cfg,利用grub启动之
  5. 例如dlxlinux,或其他
  6. 这里提供2个RTEMS操作系统的映像:hello.exe ticker.exe
  7. 也可以自己编译一个Linux内核、制作一个根文件系统,并启动之

是不是看起来好简单啊。。不过做着做着发现还是挺神烦的

1. 编译linux内核

我下的linux内核版本是2.6.32.20,和实验攻略上的版本不一样,不过我觉得内核编译的方法应该都差不多嘛~不懂问百度/谷歌嘛~

我把文件直接放到/home底下,用tar -jxvf 来解包,然后据说要用缺省编译,于是make i386_defconfig

oslab3-1

.config写好了,之后用make命令编译之,现在问题来了,它给我报了几个错,而且没有生成内核映像文件bzImage- =赶紧去百度一下…

oslab3-2

百度了一下问题解决了~理由如下(参考自http://blog.sina.com.cn/s/blog_7e49bf5e0100y4sr.html):

这个问题是由于 gcc 4.6 不再支持 linker-style 架构。将 arch/x86/vdso/Makefile 中,

以 VDSO_LDFLAGS_vdso.lds 开头所在行的 “-m elf_x86_64” 替换为 “-m64”。

以 VDSO_LDFLAGS_vdso32.lds 开头所在行的 “-m elf_x86” 替换为 “-m32”。

然后编译就木有问题啦~

oslab3-3

2. 准备一个简单的根目录和应用程序

嗯,简单的应用程序嘛~按照惯例写个hello world吧,把它保存为init.c

之后用静态编译生成可执行文件init(我后来试了如果这里不用静态编译的话在qemu中运行会出现奇怪的代码,看上去像是反汇编得到的代码?待我做完实验再去百度一下)

gcc -static -o init init.c

之后建立引导根目录映像:

1
2
3
4
5
dd if=/dev/zero of=initrd4M.img bs=4096 count=1024
mkfs.ext3 initrd4M.img
mkdir rootfs
sudo mount -o loop initrd4M.img rootfs
cp init rootfs/

准备dev 目录:

sudo mkdir rootfs/dev

linux启动过程中会启用console设备

sudo mknod rootfs/dev/console c 5 1

另外需要提供一个linux根设备,使用ram

1
2
sudo mknod rootfs/dev/ram b 1 0
sudo umount rootfs

oslab3-4

至此,一个包含简单应用程序的根目录映像myinitrd4M.img就准备好了啦啦啦~让我尝试着在qemu里面跑一下~\(≧▽≦)/~

诶…为何运行不鸟呀_(:зゝ∠)_它说我的虚拟机是i686的cpu,也就是32位的所以无法运行程序,可是我的虚拟机装的明明就是64位呀…

问了一下小伙伴发现应该用qemu-system-x86_64来启动qemu才能支持64位环境呢

1
2
qemu-system-x86_64 -kernel
./linux-2.6.32.20/arch/x86/boot/bzImage -initrd initrd4M.img -append "root=/dev/ram init=/init"

这样启动qemu就能看到输出的helloworld啦~\(≧▽≦)/~

oskab3-6

3. 用busybox 建立根文件系统来运行linux

将busybox 的包放到/home 下,解包之后用缺省编译,并设置编译选项:

make defconfig make menuconfig

如果提示用不了menuconfig的话应该是缺少ncurses包,用sudo apt-get install libncurses5-dev安装一下就好,如果提示找不到软件包就用 sudo apt-get update 更新一下软件源。不用menuconfig用字符界面的config会出人命的(~ ̄▽ ̄)~

如图配置编译选项: 在busybox settings里面把第一个勾上,静态编译它

oslab3-7

这里选as soft-links

oslab3-8

之后make编译它, 并挂载映像到rootfs 目录下

sudo mount -o loop initrd4M.img rootfs

安装busybox 到rootfs 下

cd busybox-1.23.2
sudo make CONFIG_PREFIX=../rootfs/ install 

oslab3-9

啥…它提示我的设备上空间不足_(:зゝ∠)_果然老师给的攻略比较年久失修了,攻略上的busybox版本较低只用4M就能安装好了,我的解决方法是再建了一个8M的映像initrd8M.img,我也不知还有木有更好的解决办法了。

oslab3-10

这样就算安好了busybox,可以卸载掉rootfs了

sudo umount rootfs

接着在qemu里面运行看看~\(≧▽≦)/~

qemu-system-x86_64 -kernel
./linux-2.6.32.20/arch/x86/boot/bzImage -initrd initrd4M.img -append "root=/dev/ram init=/bin/sh"

看到了busybox提供的shell就算成功喽~

oslab3-11

如果busybox没安装好,可能会看到这样:(内核它找不到shell于是吓坏了_(:зゝ∠)_)

oslab3-12

4. 制作带grub 启动的磁盘映像

首先建立软盘映像:

1
2
3
4
5
6
7
8
dd if=/dev/zero of=boot_a.img bs=512 count=2880
//在a.img 中安装grub:
sudo losetup /dev/loop0 a.img
sudo dd if=./grub-0.97-i386-pc/boot/grub/stage1 of=/dev/loop0 bs=512 count=1
sudo dd if=./grub-0.97-i386-pc/boot/grub/stage2 of=/dev/loop0 bs=512 seek=1
sudo losetup -d /dev/loop0
//在qemu 中测试是否可以进入grub:
qemu -fda a.img 

(我忘截图了…这里是成功了的_(:зゝ∠)_一般照着做都是成功的)

建立磁盘映像: 创建一个32M 的磁盘镜像文件

1
2
3
dd if=/dev/zero of=hda_32M.img bs=4096 count=8192
//给磁盘映像分区
fdisk -C 16065 -H 255 -S 63 32M.img

之后在fdisk工具里面如图操作:

oslab3-12

格式化分区 (格式化为.ext3)

1
2
sudo losetup -o 1048576 /dev/loop0 hda_32M.img
sudo mkfs.ext3 -m 0 /dev/loop0 

oslab3-13

把前面制作的bzImage 和initrd8M.img 拷贝到rootfs 目录中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sudo mount /dev/loop0 rootfs/
sudo cp linux-2.6.32.20/arch/x86/boot/bzImage ./rootfs
sudo cp initrd8M.img rootfs/ 

//为在硬盘空间里面安装grub 准备目录和文件
//在磁盘映像hda_32M.img 中创建目录来存放grub

sudo mkdir rootfs/boot
sudo mkdir rootfs/boot/grub
sudo cp ./grub-0.97-i386-pc/boot/grub/* rootfs/boot/grub

编写menu.lst,并拷贝到rootfs/boot/grub 中,menu.lst 的内容是之前截的,后来发现这里把文件名写错了,没截改过的图。(看来不能完全抄教程啊…教程上的文件名可能不一样,记得改一下哟,要不各种出错的_(:зゝ∠)_)

oslab3-14

卸载磁盘映像

1
2
3
4
5
sudo umount rootfs
sudo losetup -d /dev/loop0 //攻略上的减号是全角的!!!你妹啊这里坑了我好久!!!!

//利用grub 启动软盘,在硬盘映像上添加grub 功能
qemu-system-x86_64 -boot a -fda boot_a.img -hda hda_32M.img

oslab3-15

进来之后

1
2
root (hd0,0)
setup (hd0)

看到这个界面就对了,如果提示什么error17之类的应该是menu.lst没编对,再检查一下,要不就是没卸磁盘映像。

oslab3-16

最后测试一下,从磁盘启动grub 引导linux:

qemu-system-x86_64 -hda hda_32M.img

看~grub界面粗线啦

oslab3-17

回车进去~

oslab3-18

和刚才一样的界面~\(≧▽≦)/~说明实验做好啦~撒花撒花~

oslab3-19


参考资料:

助教君实验主页上的PDF课件(因为有一定历史了,有部分地方不太靠谱,建议不要全盘照搬攻略)

http://blog.sina.com.cn/s/blog_70dd169101013g9j.html (学长好人一生平安啊!!!我也要做好人^_^)

http://blog.sina.com.cn/s/blog_70dd169101013gcw.html