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(物理机)添加引导  

 

posted @ 2021-02-03 20:23  悟透  阅读(3162)  评论(0编辑  收藏  举报