Install ubuntu in a file on windows partition from live cd (similar to Wubi installer)

I am installing ubuntu in a file on my ntfs windows partition.

This is quite easy to do:

 - disable safe boot in bios
 - you might also need to set AHCI SSD interface access
 - boot and run live cd

open a terminal and run as root

#mount ntfs partition
mount -t ntfs /dev/nvme0n1p3 /mnt
#create installation folder
mkdir /mnt/ubuntu
#create virtual drive
mknod /dev/sdx b 7 100
#create virtual disk image
dd if=/dev/zero of=/mnt/ubuntu/ubuntu.img bs=1G count=256
#link the virtual drive to the virtual disk image
losetup /dev/sdx /mnt/ubuntu/ubuntu.img

and install ubuntu in /dev/sdx like on a separate disk.

common problems:

/dev/nvme0n1p3 not showing up
 - these are related to bios settings
mount -t ntfs /dev/nvme0n1p3 /host fail to mount
 - windows partition can be encrypted, must be disabled from windows (no need to format or reinstall windows)

to boot from the new environment I use grub config:

### BEGIN /etc/grub.d/10_linux ###
menuentry 'ubuntu' {
        rmmod tpm
        loopback loop (hd0,gpt3)/ubuntu/ubuntu.img
        root=(loop)
        linux /boot/vmlinuz-generic root=/dev/sdx rw verbose nosplash
        initrd /boot/initrd.img-generic
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
  set timeout=10
fi
### END /etc/grub.d/10_linux ###

the rmmod tpm is causing mounting loop to hang (grub 2.04)

on older versions loading ntfs driver was needed (grub 2.02)
instead of rmmod tpm, add:
modprobe ntfs

this will actually drop the boot process to initramfs shell

at this point you need to manually add commands to load the image

#create mount point needed by initramfs image
mkdir /host
#mount ntfs partition
mount -t ntfs /dev/nvme0n1p3 /host
#create virtual drive
mknod /dev/sdx b 7 100
#link the virtual drive to the virtual disk image
losetup /dev/sdx /host/ubuntu/ubuntu.img
#continue boot up
exit

this can be easily added to an initramfs scripts.

my question is, can we add this functionality to Ubuntu?

I find it easy to do and very useful. I can boot ubuntu in a native environment, but also can move my image around just like a virtual disk image.
To move my installation, I just need to follow the same steps on another instance, and just copy my ubuntu.img file from the old instance and overwrite it on the new instance.

Thanks for your interest in expanding the range of ways Ubuntu can be used.

Your argument for this configuration appears to be that the resulting install can be reused portably as a VM image, as well as being booted directly on the hardware. However, this is not truly the case: to be booted as a portable VM image the bootloader must be set up within the loopback image, and to be booted on the hardware the bootloader must be set up /outside/ the loopback image, on a boot partition.

This dual bootloader setup would be fragile, and impossible for us to support. Added to this the fact that a loopback disk will have worse disk I/O due to the added filesystem layer, I do not think this is an option we could reasonably include in the installer. Our recommendation is still to use the installer’s repartitioning support, to install Ubuntu alongside Windows instead of loop mounted from within it.

1 Like

Thank you for your consideration.
I am going to keep using ubuntu this way anyway:)

If I think about it, how is this different from installing ubuntu alogside windows?
The grub bootloader must be installed on primary partition (EFI) anyway, the difference is that it either points to another real partition (something other than windows partition), or it loads the windows partition and reads the ‘partition’ from within the file.
If somebody would format (reset) windows, or resize windows while ubuntu is set up, the bootloader would not be able to load the kernel anyway.

Maybe here I have a confusion regarding the way boot recovery works. I am not sure if by restoring (reset to factory) windows, the MBR is affected or not, so partitions are recreated or not. But ‘ubuntu’ can not control that anyway even when installing alongside windows.

I agree about the extra layer, but this is no different than running in a VM on windows.
I am not insisting for this to feature request to have any outcome if not desired, but I want to be certain and clear about what this implies, and maybe get some extra info out of this.

The way Wubi installer worked was similar, but instead of installing grub on EFI partition, it was adding an entry to the windows boot loader, and that bootloader was handling the kernel boot up.
The only difference here is that we use grub instead of windows boot loader.

Am I missing something?

I don’t know what the behavior is when Windows is reinstalled. I would expect that Windows would respect the ESP and not reformat it, or remove files from it which do not belong to Windows as an OS.

But regardless, reinstalling Windows is something of an uncommon case. Obviously if the Ubuntu image were on the NTFS partition, and that partition was reformatted, a Windows install would be even worse in terms of the impact on the Ubuntu install.

Resizing Windows should definitely not impact Ubuntu on a separate partition unless the resizing deliberately clobbered Ubuntu.

It is definitely different than running Ubuntu on the hardware, from a separate partition.

It also MAY be different than running Ubuntu in a VM on Windows, because of differences in the NTFS driver used (Windows kernel vs Linux kernel), as well as differences in the filesystem allocation by the Windows VM manager vs Ubuntu trying to install in a loopback file.

For you purposes, you might find it useful to run filesystem performance tests of the different types of configuration: Ubuntu on hardware with its own partition, Ubuntu on hardware in loopback filesystem, Ubuntu in VM under Windows in loopback filesystem.

To make the system boot up automatically, create the initramfs script
/usr/share/initramfs-tools/scripts/init-premount/mount:

#!/bin/sh

# init-premount script for mounting virtual disk image.

PREREQS=""
prereqs()
{
        echo $PREREQS
}

case ${1} in
        prereqs)
                prereqs
                exit 0
                ;;
esac

mknod /dev/sdx b 7 100
mkdir /host
mount -t ntfs /dev/nvme0n1p3 /host
losetup /dev/sdx /host/ubuntu/ubuntu.img

make it executable:

chmod +x /usr/share/initramfs-tools/scripts/init-premount/mount

and update initramfs image:

update-initramfs -u

on newer versions of kernel and losetup, the ‘losetup /dev/sdx /host/ubuntu/ubuntu.img’ command won’t work. a simple workaround would be to use instead of:

mknod /dev/sdx b 7 100
losetup /dev/sdx /host/ubuntu/ubuntu.img

the following (use everywhere):

losetup /dev/loop0 /host/ubuntu/ubuntu.img
ln -s /dev/loop0 /dev/sdx