实验目的
通过制作grub启动软盘,理解linux启动引导的机制
实验内容
- 准备qemu
- 制作带busybox的linux内核映像
- 制作带grub的磁盘映像
具体过程
- 安装qemu
su
(super user)获得root权限,以后就不用按sudo
了- ubuntu12.04.5-desktop-i386中使用
apt-get install qemu
- 编译Linux内核
- 获得linux2.6.38
tar -zxvf LINUX_KERNEL
解压cd FOLDER
进入解压后的目录make help
查看一下编译信息make i386_defconfig
进行i386缺省编译make
编译- 可以看到最后有bzImage生成了,位于:
arch/x86/boot/bzImage
- 准备一个init可执行文件用于在linux启动时执行
vim PATH/hello.c
- 写入
#include <stdio.h>
int main(){
while(1)
printf("hello world!");
return 0;
}
-
wq
保存并退出后,gcc -static -o init hello.c
生成了init可执行文件 -
建立根目录引导镜像
dd if=/dev/zero of=./initrd.img bs=4096 count=1024
生成一个4M空的镜像mkfs.ext3 initrd.img
将该镜像文件格式改成ext3mkdir rootfs
生成一个文件夹用于镜像挂载mount -o loop initrd.img rootfs
将镜像作为回环设备挂载cp PATH/init rootfs
将之前的init复制到rootfs中作为启动文件mkdir rootfs/dev
创建dev目录mknod rootfs/dev/console c 5 1
一个console设备mknod rootfs/dev/ram b 1 0
提供一个linux根设备umount rootfs
解除挂载qemu-kernel-i386 -kernel PATH_TO_LINUX/arch/x86/boot/bzImage -initrd initrd.img -append "root=/dev/ram init=/init"
- 可以看到在qemu中我们成功的运行了
init
-
建立根文件系统
- 下载busybox_1.25.1.tar.bz2
- 解压t
ar -xvf FILE
并进入目录cd FOLDER
make defconfig
进行缺省编译make menuconfig
-
- 修改
busybox settings–>build options–>build busybox as a static binary(no share libs)
把BusyBox编译成静态链接的可执行文件,运行时才独立于其他函数库,否则必须要其他库文件才能运行 Busybox Settings -> Installation Options- > Don’t use /usr
原有配置在make install后BusyBox将安装在原系统的/usr下,这将覆盖系统原有的命令。选择这个选项后,make install后会在BusyBox目录下生成一个叫_install的目录,里面有BusyBox和指向他的链接busybox settings –> installation options as soft-links
make
编译mount -o loop initrd.img PATH/rootfs
将之前的镜像挂到rootfs上去make CONFIG_PREFIX=PATH/rootfs install
将busybox安装到镜像中umount PATH/rootfs
解除挂载qemu-system-i386 -kernel PATH_TO_LINUX/arch/x86/boot/bzImage -initrd initrd4M.img -append "root=/dev/ram init=/bin/sh"
- 可以用ls和运行init
- 修改
-
制作带grub启动的磁盘映像
- 获得grub的源码
- 解压
tar -zxvf
dd if=/dev/zero of=a.img bs=512 count=2880
建立软盘映像losetup -f
获得一个可以用的loop设备(例如:/dev/loop0)losetup /dev/loop0 a.img
dd if=./grub-0.97-i386-pc/boot/grub/stage1 of=/dev/loop0 bs=512 count=1
if=./grub-0.97-i386-pc/boot/grub/stage1 of=/dev/loop0 bs=512 count=1
安装grub到软盘losetup -d /dev/loop0
qemu-system-i386 -fda a.img
尝试进入grubdd if=/dev/zero of=hda_32M.img bs=4096 count=8192
建立一个磁盘镜像文件fdisk -C 16065 -H 255 -S 63 b.img设置hda_32M.img
的磁头数为255、磁道数为16065、扇区数为63,同时给磁盘分区。这里我们只分一个区,并设置该分区为引导分区- 在fdisk界面中依次输入"n"(创建新表),"p"创建主分区,默认使用1为第一个分区(回车),"a"以切换a可引导标志,"w"保存更改
kpartx -av /dev/loop0
更新映像文件,或许kpartx需要apt-get install
一下
losetup -o 1048576 /dev/loop0 b.img
把前面的2048个扇区(0~2047)作为引导扇区使用,格式化分区从第2048个扇区开始,所以1048576=2048*512mkfs.ext3 -m 0 /dev/loop0
把分区初始化为ext3格式mount /dev/loop0 rootfs/
cp linux-2.6.38/arch/x86/boot/bzImage ./rootfs
cp initrd.img rootfs
把前面制作的bzImage和initrd4M.img拷贝到镜像中mkdir rootfs/boot
mkdir rootfs/boot/grub
cp ./grub-0.97-i386-pc/boot/grub/* rootfs/boot/grub
在磁盘映像中创建目录存放grub- 在rootfs/boot/grub中编写menu.lst
default 0
timeout 30
title linux on b.img
root (hd0,0)
kernel (hd0,0)/bzImage root=/dev/ram init=/bin/ash
initrd (hd0,0)/initrd.imgumount rootfs
losetup –d /dev/loop0
卸载磁盘映像qemu-system-i386 -boot a -fda a.img -hda b.img
root (hd0,0)
setup (hd0)
qemu-system-i386 -hda b.img
- 回车后出现
实验总结
老师教会了我们一个非冯的计算机结构,即代码存储于ppt和我们贫瘠的大脑而不是计算机中??,我们为了这非凡的设想心甘情愿地寻找老师环境,在各位学长的blog的帮助下,我们终于理解了实践是检验真理唯一标准的真理,体会了与时俱进的重要性,深深感到今天的幸福是多么的来之不易
参考资料
制作可用grub引导Linux系统的磁盘映像文件 一
制作可用grub引导Linux系统的磁盘映像文件 二
陈香兰老师的pdf
How to run RTEMS on QEMU