Windows不分区VHD装Linux多系统(四):VM虚拟机里Ubuntu18引导修改
上一篇:Windows不分区VHD装Linux多系统(三):VM虚拟机安装ubuntu18.04
下一篇:Windows不分区VHD装Linux多系统(五):Win7(物理机)添加引导
########################################################################################
这里要先感谢
无忧论坛 和 论坛里niumao
我将niumao的教程做进一步实践整理,避免新人踩坑。
#########################################################################################
如果你用VHD引导win系统那很容易。只是在上篇装ubuntu18改成装windows系统就可以了。
在VHD中装Ubuntu最终目的还是要让物理机能引导VHD开启ubuntu,但是默认的引导不能满足要求。
说下VHD引导Ubuntu的思路(是无忧论坛里2011niumao大佬的想法):
开机,引进到grub4dos-->vmlinuz-5.4.0-42-generic --> initrd.img-5.4.0-42-generic--自动识别挂载VHD,进入ubuntu系统。
关键是initrd.img-5.4.0-42-generic里不认识VHD这个文件,因为是Win公司的程序。
那么就用kpartx来识别挂载VHD,这时就需要重新编译ubuntu里的initrd.img-5.4.0-42-generic文件,把kpartx添加进去。
(可以用其他的引导,这里grub4dos举例)
更详细使用请看2011niumao大佬提供的readme-ubuntukloop.zip压缩包里 PDF说明文件
下载:https://pan.baidu.com/s/18NTBbzlVLdHXxUcnpXFMNw 提取码 w4af
向虚拟机里传输文件:
思路一,安装VM自带的VM-tool ,安装麻烦,而且会在之后正常引导后有残留文件,也有可能影响系统。
思路二,在物理机win7系统上建立网页(http)和ftp服务,这样就可以上传下载文件了。(这个方便 ,选这个)
思路三,DiskGenius-v5.1.1.696 专业版也可以访问磁盘内容,ubuntu 系统的磁盘格式是EXT4的,所以要新版才支持。
其他版本4.8不支持EXT4,只能看到磁盘看不到文件和文件夹。修改过的文件要重新加载磁盘才能显示新文件。
注意这个工具只能从虚拟机里拷到物理机里文件,反之不行(因为权限问题)。
这个工具好处就是即便虚拟机开机情况下,也可以使用。
在物理机win7上开启网页服务器和FTP服务器,把文件传输到虚拟机的ubuntu18里。
在解压的文件夹中找到MyWebServer.exe这个软件运行,点击浏览 选择任意一个目录,做为网站的服务目录,这在桌面新建一个web文件夹来存放文件。
点浏览选择web目录,点击启动(Start)
FTP服务器也一样
在物理机上打开CMD窗口,看看物理机的IP是多少,命令行输入ipconfig /all,我的IP是 192.168.3.11(你的不一定和我的一样)
C:\Users\Administrator>ipconfig /all
测试:
打开浏览器 输入你的IP ,我的这里是192.168.3.11,看到有列表的文件夹和文件,
说明就可以了,你的web文件夹里也随便放点东西,要不显示不出来。
好了,网页服务能正常访问。
启动VM虚拟机进入ubuntu18系统里,我们先修改apt源为163的。国外的源太慢了。
在ubuntu18里,在桌面右键--打开终端,先看看对外网的范围能不能通
输入下面命令,看到有64bytes开头的返回值 就说明网是通的。
$ ping -c 2 baidu.com
备份默认源
$ cd /etc/apt $ sudo cp sources.list{,.bak} $ ll
更换apt-get源一:推荐
设置apt-get源为aliyun(阿里云) 桌面--左下角九个点--全软件和更新--ubuntu软件--下载自--其他站点--中国--mirrors.aliyun.com--选择服务器 等待自动更新完成
更换apt-get源二:
在ubuntu18里打开火狐浏览器,输入物理机的IP地址,下载sources.list脚本文件运行来更换apt-get源
保存文件,默认是保存到当前用户的 主目录/下载文件夹里
重复上面操作,将local 、mkinitramfs、ntfs_3g 这几个文件下载下来(linux文件没有后缀,不像win的文件)
打开终端输入,中文输入,点右上角那个zh(英)来切换输入法
$ sudo mv /etc/apt/sources.list{,.bak} $ sudo mv ~/下载/sources.list /etc/apt/
源安装完,执行更新命令
$ sudo apt-get update
等一会,下载完成
apt-get源更换结束
======================= 开始修改 ====================================
总结,要修改的文件:
init (修改 4 处) local (修改 3 处) mkinitramfs (修改 1 处) modules (修改 1 处) ntfs_3g (修改 1 处)
安装所用的软件
$ sudo apt-get install kpartx kpartx-boot util-linux dmsetup lvm2 lftp
备份文件、将下载的文件移动到对应目录
$ sudo cp /usr/share/initramfs-tools/init{,.bak} $ sudo cp /usr/share/initramfs-tools/scripts/local{,.bak} $ sudo cp /usr/sbin/mkinitramfs{,.bak} $ sudo cp /etc/initramfs-tools/modules{,.bak} $ sudo cp /usr/share/initramfs-tools/scripts/local-bottom/ntfs_3g{,.bak} $ sudo mv ~/下载/local /usr/share/initramfs-tools/scripts/ $ sudo mv ~/下载/mkinitramfs /usr/sbin/ $ sudo mv ~/下载/ntfs_3g /usr/share/initramfs-tools/scripts/local-bottom/ $ sudo chmod 777 /usr/sbin/mkinitramfs
编辑文件一:init (修改 4 处) $ sudo gedit /usr/share/initramfs-tools/init
一处:
修改init里面约第32行的 mount -t tmpfs -o "noexec,nosuid,size=10%,mode=0755" tmpfs /run 修改为 mount -t tmpfs -o "noexec,size=20%,mode=0755" tmpfs /run 就是删除 nosuid, 选项。
二处:
在大约67行处增加 export KLOOP= export KROOT= export KLVM= export HOSTFSTYPE= export KLOOPFSTYPE= export SQUSHFS= export UPPERDIR= export LOWERDIR= export WORKDIR= export QEMUNBD=
三处:
在大约229行处增加 kloop=*) KLOOP=${x#kloop=} ;; kroot=*) KROOT=${x#kroot=} ;; klvm=*) KLVM=${x#klvm=} ;; hostfstype=*) HOSTFSTYPE=${x#hostfstype=} ;; kloopfstype=*) KLOOPFSTYPE=${x#kloopfstype=} ;; squashfs=*) SQUASHFS=${x#squashfs=} ;; upperdir=*) UPPERDIR=${x#upperdir=} ;; lowerdir=*) LOWERDIR=${x#lowerdir=} ;; workdir=*) WORKDIR=${x#workdir=} ;; qemunbd=*) QEMUNBD=${x#qemunbd=} ;;
四处:
在大约376行处增加 unset kloop unset kroot unset klvm unset hostfstype unset kloopfstype unset squashfs unset upperdir unset lowerdir unset workdir unset qemunbd
修改init执行权限、所属用户和组。(防止出现引导过程中找不到Init文件。Failed to execute /init Error -13)
sudo chmod 755 /usr/share/initramfs-tools/init sudo chown root:root /usr/share/initramfs-tools/init
编辑文件二:local (修改 3 处) $ sudo gedit /usr/share/initramfs-tools/scripts/local
一处:
在约191行增加 if [ -z "$KLOOP" ] && [ -z "$SQUASHFS" ] && [ -z "$UPPERDIR" ] && [ -z "$QEMUNBD" ] ; then
二处:
在约260行增加 fi
三处:
在约261行增加 ######################################################### # kloop by niumao # ######################################################### if [ -n "$KLOOP" ]; then ### reset the value of the root variable HOSTDEV="${ROOT}" NEWROOT="${rootmnt}" [ -n "$KROOT" ] && ROOT="$KROOT" [ -n "$KROOT" ] || ROOT="/dev/loop0" export ROOT realroot="$ROOT" ### auto probe the fs-type of the partition in which vhd-file live and mount it /host mkdir -p /host if [ -e ${NEWROOT}${KLOOP} ]; then mount --move $NEWROOT /host else if [ -z "$HOSTFSTYPE" ]; then HOSTFSTYPE="$(blkid -s TYPE -o value "${HOSTDEV}")" [ -z "$HOSTFSTYPE" -o "${HOSTFSTYPE}" = "ntfs" ] && HOSTFSTYPE="ntfs-3g" fi [ "${HOSTFSTYPE}" = "ntfs-3g" ] || modprobe ${HOSTFSTYPE} mount -t ${HOSTFSTYPE} -o rw ${HOSTDEV} /host fi ### mount the vhd-file on a loop-device if [ "${KLOOP#/}" != "${KLOOP}" ]; then modprobe loop kpartx -av /host${KLOOP} [ -e "$realroot" ] || sleep 3 fi ### probe lvm on vhd-file if [ -n "$KLVM" ]; then modprobe dm-mod vgscan vgchange -ay ${KLVM} [ -e "$realroot" ] || sleep 3 fi if [ "${readonly}" = "y" ] ; then roflag="-r" else roflag="-w" fi ### mount the realroot / in vhd-file on $NEWROOT if [ -z "${KLOOPFSTYPE}" ]; then KLOOPFSTYPE="$(blkid -s TYPE -o value "$realroot")" [ -z "${KLOOPFSTYPE}" ] && KLOOPFSTYPE="ext4" fi [ -e "$realroot" ] || sleep 3 mount ${roflag} -t "${KLOOPFSTYPE}" $realroot $NEWROOT ### mount /host in initrd to /host of the realrootfs [ -d ${NEWROOT}/host ] || mkdir -p ${NEWROOT}/host mount --move /host ${NEWROOT}/host fi if [ -n "$SQUASHFS" ]; then ### reset the value of the root variable HOSTDEV="${ROOT}" NEWROOT="${rootmnt}" ### auto probe the fs-type of the partition in which vhd-file live and mount it /host mkdir -p /host if [ -e ${NEWROOT}${SQUASHFS} ]; then mount --move $NEWROOT /host else if [ -z "$HOSTFSTYPE" ]; then HOSTFSTYPE="$(blkid -s TYPE -o value "${HOSTDEV}")" [ -z "$HOSTFSTYPE" -o "${HOSTFSTYPE}" = "ntfs" ] && HOSTFSTYPE="ntfs-3g" fi [ "${HOSTFSTYPE}" = "ntfs-3g" ] || modprobe ${HOSTFSTYPE} mount -t ${HOSTFSTYPE} -o rw ${HOSTDEV} /host fi ###try to boot from squashfs modprobe overlay mkdir -p /run/lowerdir /run/upperdir /run/workdir mount /host$SQUASHFS /run/lowerdir mount -t overlay overlay -o lowerdir=/run/lowerdir,upperdir=/run/upperdir,workdir=/run/workdir $NEWROOT ### mount /host in initrd to /host of the realrootfs [ -d ${NEWROOT}/host ] || mkdir -p ${NEWROOT}/host mount --move /host ${NEWROOT}/host fi if [ -n "$UPPERDIR" ] && [ -n "$WORKDIR" ]; then ### reset the value of the root variable HOSTDEV="${ROOT}" NEWROOT="${rootmnt}" ### auto probe the fs-type of the partition in which vhd-file live and mount it /host mkdir -p /host if [ -e ${NEWROOT}${UPPERDIR} ]; then mount --move $NEWROOT /host else if [ -z "$HOSTFSTYPE" ]; then HOSTFSTYPE="$(blkid -s TYPE -o value "${HOSTDEV}")" [ -z "$HOSTFSTYPE" -o "${HOSTFSTYPE}" = "ntfs" ] && HOSTFSTYPE="ntfs-3g" fi [ "${HOSTFSTYPE}" = "ntfs-3g" ] || modprobe ${HOSTFSTYPE} mount -t ${HOSTFSTYPE} -o rw ${HOSTDEV} /host fi ###try to boot from dir modprobe overlay mkdir /run/lowerdir mount -t overlay overlay -o lowerdir=/run/lowerdir,upperdir=/host$UPPERDIR,workdir=/host$WORKDIR $NEWROOT ### mount /host in initrd to /host of the realrootfs [ -d ${NEWROOT}/host ] || mkdir -p ${NEWROOT}/host mount --move /host ${NEWROOT}/host fi if [ -n "$QEMUNBD" ] ; then ### reset the value of the root variable HOSTDEV="${ROOT}" NEWROOT="${rootmnt}" [ -n "$KROOT" ] && ROOT="$KROOT" [ -n "$KROOT" ] || ROOT="/dev/loop0" export ROOT realroot="$ROOT" ### auto probe the fs-type of the partition in which vhd-file live and mount it /host mkdir -p /host if [ -e $NEWROOT$QEMUNBD ]; then mount --move $NEWROOT /host else if [ -z "$HOSTFSTYPE" ]; then HOSTFSTYPE="$(blkid -s TYPE -o value "${HOSTDEV}")" [ -z "$HOSTFSTYPE" -o "${HOSTFSTYPE}" = "ntfs" ] && HOSTFSTYPE="ntfs-3g" fi [ "${HOSTFSTYPE}" = "ntfs-3g" ] || modprobe ${HOSTFSTYPE} mount -t ${HOSTFSTYPE} -o rw ${HOSTDEV} /host fi ### mount the vhd-file on a loop-device if [ "${QEMUNBD#/}" != "${QEMUNBD}" ]; then modprobe nbd max_part=8 modprobe loop [ -e /dev/nbd0 ] || sleep 3 qemu-nbd -c /dev/nbd0 /host${QEMUNBD} kpartx -av /dev/nbd0 [ -e "$realroot" ] || sleep 3 fi if [ "${readonly}" = "y" ] ; then roflag="-r" else roflag="-w" fi ### mount the realroot / in vhd-file on $NEWROOT if [ -z "${KLOOPFSTYPE}" ]; then KLOOPFSTYPE="$(blkid -s TYPE -o value "$realroot")" [ -z "${KLOOPFSTYPE}" ] && KLOOPFSTYPE="ext4" fi [ -e "$realroot" ] || sleep 3 mount ${roflag} -t "${KLOOPFSTYPE}" $realroot $NEWROOT ### mount /host in initrd to /host of the realrootfs [ -d ${NEWROOT}/host ] || mkdir -p ${NEWROOT}/host mount --move /host ${NEWROOT}/host fi ######################################################### # kloop by niumao # #########################################################
编辑文件三:mkinitramfs (修改 1 处) $ sudo gedit /usr/sbin/mkinitramfs
处一:
在约320处添加 # util-linux,added by niumao copy_exec /sbin/blkid /sbin copy_exec /sbin/losetup /sbin copy_exec /sbin/kpartx /sbin copy_exec /bin/ntfs-3g /bin copy_exec /sbin/vgscan /sbin copy_exec /sbin/shutdown /shutdown copy_exec /usr/bin/qemu-nbd /bin touch ${DESTDIR}/etc/initrd-release touch ${DESTDIR}/version
编辑文件四:向modules文件追加三行内容,loop、fuse、dm-mod /etc/initramfs-tools/modules
$ sudo echo "loop" >> /etc/initramfs-tools/modules $ sudo echo "fuse" >> /etc/initramfs-tools/modules $ sudo echo "dm-mod" >> /etc/initramfs-tools/modules $ sudo echo "overlay " >> /etc/initramfs-tools/modules
编辑文件五:向ntfs_3g文件增加内容 $ sudo gedit /usr/share/initramfs-tools/scripts/local-bottom/ntfs_3g
替换ntfs-3g目的是防止关机出现 buffer I/O 错误和引导阶段能够以可写方式挂载ntfs分区上的vhd(如果没有错误可以不替换ntfs_3g)
注:以下ntfs-3g代码原作者更新时间(2021-0311,更新链接)
#!/bin/sh set -e case "${1}" in prereqs) exit 0 ;; esac if [ "${ROOTFSTYPE}" = ntfs ] || [ "${ROOTFSTYPE}" = ntfs-3g ] || \ [ "${LOOPFSTYPE}" = ntfs ] || [ "${LOOPFSTYPE}" = ntfs-3g ] || [ -n "$KLOOP" ] || [ -n "$SQUASHFS" ] then mkdir -p /run/sendsigs.omit.d pidof @ount.ntfs-3g >> /run/sendsigs.omit.d/ntfs-3g fi exit 0
注:以下ntfs-3g代码原作者更新时间(2020-0307),此文件弃用,用上面的
#!/bin/sh ##set -e ##case "${1}" in ## prereqs) ## exit 0 ## ;; ##esac if [ "${ROOTFSTYPE}" = ntfs ] || [ "${ROOTFSTYPE}" = ntfs-3g ] || \ [ "${LOOPFSTYPE}" = ntfs ] || [ "${LOOPFSTYPE}" = ntfs-3g ] || [ -n "$KLOOP" ] || [ -n "$SQUASHFS" ] || [ -n "QEMUNBD" ] 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 pidof qemu-nbd >> /run/sendsigs.omit.d/qemu-nbd 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
开始生成initrd.img文件,查看当前/boot 目录下的initrd.img文件版本
$ ls /boot
下面的版本号填你自己看到的,这里是5.4.0-42
$ sudo /usr/sbin/mkinitramfs -o ~/initrd.img-5.4.0-42-generic
注:参数-o,o是小写
不出意外的话可以在home(主目录)中找到生成的文件
接着,把initrd.img-5.4.0-42-generic、vmlinuz-5.4.0-42-generic用FTP软件传回到物理机上。
上面的install命令中已经安装好了FTP客户端,这时也保证物理机上的FTP服务软件启动状态。
向物理机传文件
$ lftp 192.168.3.11 ftp> put ~/initrd.img-5.4.0-42-generic ftp> put /boot/vmlinuz-5.4.0-42-generic
将ubuntu里的文件拷贝出来和装好ubuntu的vhd文件放同一目录。
下一篇:Windows不分区VHD装Linux多系统(五):Win7(物理机)添加引导