|  | 
推荐
 
 
 楼主|
发表于 2014-6-29 15:37:28
|
只看该作者 
| 本帖最后由 2011niumao 于 2014-12-13 18:34 编辑 
 UBUNTU制作可以引导VHD系统的initrd.img 的方法
 http://pan.baidu.com/s/1mgFi1Qg
 
 0.在windows系统下
 使用virtualbox软件建立固定大小的vhd虚拟磁盘文件.
 推荐16g大小.注意不可以使用动态大小的vhd,只能使用固定大小的vhd.
 下载并使用UBUNTU安装盘将UBUNTU系统安装在vhd上面====只分一个主分区来挂载/目录.分成多个主分区请看注释。
 
 注释:分成多个主分区也可以的。如果有多个分区,注意修改vlooppart参数的值,使得它指向/分区。例如vhd分三个区,/挂载在第三个分区,则引导参数改为 vlooppart=p3。此外不支持逻辑分区。所以如果分区较多,可以使用gpt格式磁盘。如果不分区或分区个数不超过4,可以使用mbr格式并把所有分区设定为主分区。
 
 以下制作能够直接引导vhd内UBUNTU系统的initrd.img文件:
 
 1.首先安装kpartx,kpartx-boot,util-linux,dm-setup一些软件。
 可以在新立得中搜索安装。也可以使用命令。
 打开一个终端,输入
 
 复制代码sudo apt-get install kpartx kpartx-boot util-linux dmsetup
2.修改两个文件:local  mkinitramfs
 先备份两个文件
 
 复制代码sudo cp /usr/share/initramfs-tools/scripts/local ./local.backup
sudo cp /usr/sbin/mkinitramfs ./mkinitramfs.backup
再依次修改两个文件:
 修改local文件
 
 复制代码sudo gedit /usr/share/initramfs-tools/scripts/local
再将本附件所带的local文件用gedit打开,找到如下部分
 
 复制代码        ##############################################################
        #                         TO BOOT FROM VHD                   #
        ##############################################################
        for x in $(cat /proc/cmdline); do
        case $x in
        vloop=*)
                VLOOP="${x#vloop=}"
                ;;
        vlooppart=*)
                VLOOPPART="${x#vlooppart=}"
                ;;
        vloopfstype=*)
                VLOOPFSTYPE="${x#vloopfstype=}"        
                ;;
        vloopcheck=*)
                VLOOPCHECK="${x#vloopcheck=}"        
                ;;
        esac
        done
        if [ "$VLOOP" ]; then
                if [ "$mountroot_status" != 0 ]; then
                        if [ ${FSTYPE} = ntfs ] || [ ${FSTYPE} = vfat ]; then
                                panic "
                Could not mount the partition ${ROOT}.
                This could also happen if the file system is not clean because of an operating
                system crash, an interrupted boot process, an improper shutdown, or unplugging
                of a removable device without first unmounting or ejecting it.  To fix this,
                simply reboot into Windows, let it fully start, log in, run 'chkdsk /r', then
                gracefully shut down and reboot back into Windows. After this you should be
                able to reboot again and resume the installation.
                (filesystem = ${FSTYPE}, error code = $mountroot_status)"
                        fi
                fi
        
                mkdir -p /host
                mount -o move ${rootmnt} /host
                str=${VLOOP}
                disk_files="/host${str}"                        
                
                # FIXME This has no error checking
                modprobe loop
                kpartx -av "${disk_files}"
                sleep 3
                
                # Get the vloop filesystem type if not set
                if [ -z "${VLOOPFSTYPE}" ]; then
                        FSTYPE="unknown"
                else
                        FSTYPE="${VLOOPFSTYPE}"
                fi
                if [ "$FSTYPE" = "unknown" ] && [ -x /sbin/blkid ]; then
                        FSTYPE=$(/sbin/blkid -s TYPE -o value "/dev/mapper/loop0${VLOOPPART}")
                        [ -z "$FSTYPE" ] && FSTYPE="ext4"
                fi
                
                if [ ${readonly} = y ]; then
                        roflag=-r
                else
                        roflag=-w
                fi
                
                [ -z "$VLOOPCHECK" ] && VLOOPCHECK="no"
                if [ "$VLOOPCHECK" = "yes" ] ; then
                echo "checking vloop / filesystem, please wait....."
                fsck.${FSTYPE} -a "/dev/mapper/loop0${VLOOPPART}"
                fi
                        
                mount -t ${FSTYPE} "/dev/mapper/loop0${VLOOPPART}" ${rootmnt}        
                if [ -d ${rootmnt}/host ]; then
                        mount -o move /host ${rootmnt}/host
                fi
        fi 
        ##############################################################
        #                     end,      TO BOOT FROM VHD             #
        ##############################################################
拷贝到/usr/share/initramfs-tools/scripts/local 文件的相同位置处。
 这个位置在文件最后几行上面,最后结果,接着上面的这段后面是以下几行。
 
 复制代码[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
        run_scripts /scripts/local-bottom
        [ "$quiet" != "y" ] && log_end_msg
}
该文件结束。
 
 注释: 新增两个控制参数: vloopfstype=ext4 ---说明vhd中根文件系统的文件系统类型。
 vloopcheck=yes 或 no  ---控制启动时强制做一次磁盘检查。比较简陋。如果没有特殊需要不用理会。
 3 修改mkinitramfs文件
 
 复制代码sudo gedit /usr/sbin/mkinitramfs
找到# util-linux,在其下插入以下几行:
 
 复制代码copy_exec /sbin/losetup /sbin
copy_exec /sbin/kpartx /sbin
copy_exec /sbin/shutdown /shutdown
cp -a /sbin/fsck*  ${DESTDIR}/sbin/
copy_exec /sbin/e2fsck /sbin
touch ${DESTDIR}/etc/initrd-release
touch ${DESTDIR}/version
最后该处几个语句为
 
 复制代码# util-linux
copy_exec /sbin/blkid /sbin
copy_exec /sbin/losetup /sbin
copy_exec /sbin/kpartx /sbin
copy_exec /sbin/shutdown /shutdown
cp -a /sbin/fsck*  ${DESTDIR}/sbin/
copy_exec /sbin/e2fsck /sbin
touch ${DESTDIR}/etc/initrd-release
touch ${DESTDIR}/version
记得保存一下。
 
 第四步第五步可选。不执行也可以的。实际上只有在使用ubuntu内核引导其他LINUX发行版
 特别是使用systemd的发行版时候才需要第四步第五步。但是据说UBUNTU在14.10版本也要
 使用systemd了。所以这一步到时候也许也必须作了。其方法来自于互联网
 http://www.freedesktop.org/wiki/ ... RootStorageDaemons/
 http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface/
 
 4.附件ntfs-3g_ntfsprogs-2014.2.15.fixed 是已经修改好的ntfs-3g源码.
 对他手工编译安装.
 打开一个终端.进入该目录.依次执行以下命令:
 
 复制代码./configure
make
sudo make install
(这一步是为了在使用了 systemd 的linux系统中避免关机时候出现 buffer I/O 错误
 ====UBUNTU计划在14.10版中使用systemd
 ====也许到时候会有官方的避免出现 buffer  I/O 错误的机制 发布出来.
 目前只有这个重编译 ntfs-3g源码 的方法====实际上是 systemd 官方推荐的方法)
 
 
 5.编辑文件:/usr/share/initramfs-tools/scripts/local-bottom/ntfs_3g .
 
 
 复制代码sudo gedit /usr/share/initramfs-tools/scripts/local-bottom/ntfs_3g
将以下拷贝覆盖原始内容即可。
 
 复制代码#!/bin/sh
##set -e
##case "${1}" in
##        prereqs)
##                exit 0
##                ;;
##esac
if [ "${ROOTFSTYPE}" = ntfs ] || [ "${ROOTFSTYPE}" = ntfs-3g ] || \
   [ "${LOOPFSTYPE}" = ntfs ] || [ "${LOOPFSTYPE}" = ntfs-3g ]
then
        mkdir -p /run/sendsigs.omit.d
        pidof mount.ntfs >> /run/sendsigs.omit.d/ntfs-3g
        pidof mount.ntfs-3g >> /run/sendsigs.omit.d/ntfs-3g
fi
#####################################################################
##the following maybe help to resolve the buffer I/O error problem 
##when reboot or halt.
#####################################################################
if [ -d /run/initramfs -a -f /init ]
then
        mkdir -p /run/initramfs/dev /run/initramfs/host /run/initramfs/proc /run/initramfs/root /run/initramfs/run /run/initramfs/sys /run/initramfs/tmp
        rm -rf   /lib/modules
        for xxx in /*
          do        
        if [ ${xxx} = "/dev" -o ${xxx} = "/host" -o ${xxx} = "/proc" -o ${xxx} = "/root" -o ${xxx} = "/run" -o ${xxx} = "/sys" -o ${xxx} = "/tmp" ];
        then
                :
        else
                cp -a ${xxx} /run/initramfs/  1>/dev/null 2>&1;
        fi
        done
        unset xxx
fi
####################################################################
exit 0
 
 6.生成initrd.img文件
 
 复制代码sudo /usr/sbin/mkinitramfs -o ~/initrd.img (可以加上版本号得到其他内核版本的initrd.img)
7,引导设置有两种方式: grub2 grub4dos .
 当然最好是自动搜索确定UUID并把它传给内核.
 这样只需要设置启动到grub4dos grub2就可以了.不需要手工修改menu.lst grub.cfg.
 而设置启动,对于win7 可以使用bootice编辑修改BCD文件.对于winxp,可以编辑修改boot.ini文件做到.
 参看 grub通用启动器20130724 的说明.
 
 
 grub4dos比较简单好用,但是不能用于UEFI-gpt的电脑.只能用于BIOS-MBR.
 grub4dos自动搜索UUID的菜单例子
 
 复制代码title VBUNTUFIX uuid-auto-probe
find --set-root --ignore-floppies --ignore-cd /vbuntufix/vbuntufix.vhd
uuid ()
kernel /vbuntufix/vmlinuz  root=UUID=%?% vloop=/vbuntufix/vbuntufix.vhd vlooppart=p1 
initrd /vbuntufix/initrd.img
grub2适用于UEFI与 BIOS,应用范围较广。
 grub2自动探测UUID的菜单
 
 复制代码menuentry 'VBUNTUFIX linux' --class ubuntu --class gnu-linux --class gnu --class os {
        recordfail
        insmod gzio
        insmod part_msdos
        insmod part_gpt
        insmod ext2
        insmod ntfs
        insmod probe
        insmod search
        search --no-floppy -f --set=aabbcc /vbuntufix/vbuntufix.vhd
        set root=${aabbcc}
        probe -u --set=ddeeff ${aabbcc}
        linux        /vbuntufix/vmlinuz root=UUID=${ddeeff} vloop=/vbuntufix/vbuntufix.vhd vlooppart=p1 
        initrd        /vbuntufix/initrd.img
}
 | 
 |