Sunday, 24 December 2017

Resize EFI partition


When installing respun Ubuntu or similar distros on Intel Apollo Lake devices using the '-b Linuxium'  option (or '--apollo') one issue that might be encountered is where the EFI partition isn't large enough to store the bootable EFI file. Some Windows installations only create a 60MB partition which after installing the Windows EFI files leaves only around 30MB free. With the later Linux kernel releases the size and number of modules have increased and the generated bootable EFI file is now quite large (over 50MB) and if there is insufficient space for it the resultant installation will not boot.

The solution is to increase the size of the EFI partition. Unfortunately this cannot be achieved through a simple command so I've written some instructions that whilst appearing somewhat complicated will achieve the required result.

Before embarking on using the instructions I highly recommend creating a backup image of your eMMC to use as recovery should the need arise.

The resizing process involves creating a 'Windows 10 installation and repair' USB, removing the existing EFI partition and then creating a new one using the 'repair' USB. If Ubuntu or similar was previously installed then additional steps are required to save and then restore the Ubuntu EFI files and to update the GRUB bootloader if used. You will need a working internet connection and two USBs (both minimum 8GB) and start by 'dd'ing an Ubuntu ISO to one of them.

Then to increase the EFI partition when only Windows is installed use the following instructions:


1. Boot Windows
REM right-click the Windows icon (bottom-left corner on the desktop) and select 'Disk Management'
REM right-click the Windows volume and then click 'Shrink Volume'
REM assume new EFI partition will be 150MB so enter '150' in the 'Enter the amount of space to shrink in MB' box and click 'Shrink'
REM when the shrink operation has completed an area of '150 MB Unallocated' space should appear

2. Boot from Ubuntu LiveUSB
# remove NVRAM entries for Windows
sudo efibootmgr -b $(efibootmgr -v | grep Windows | sed 's/\*.*//' | sed 's/Boot//' | head -1) -B
# delete EFI partition
DISK=$(blkid | grep -i "EFI System Partition" | sed 's/p.*//')
sudo sgdisk --delete=$(sudo gdisk -l ${DISK} | grep -i "EFI System Partition" | awk '{print $1}') ${DISK}



3. Still in Ubuntu create a 'Windows 10 installation and repair' USB
# go to 'https://www.microsoft.com/en-au/software-download/windows10ISO' in a browser
select 'Windows 10' and click 'Confirm'
select 'English International' and click 'Confirm'
select '64-bit Download' and click 'Confirm'
# wait for ISO to download
# confirm ISO has successfully downloaded
ls -ltr ~/Downloads | tail -1
# insert the other the USB
USB=$(ll /dev/disk/by-id/ | grep usb | head -1 | sed 's?.*/??')
# unmount any mounted partitions
sudo umount /dev/${USB}*
# initialize the USB
sudo sgdisk -Z /dev/${USB}
# create a single partition on the USB
sudo sgdisk --new=0:0:0 /dev/${USB}
# create a FAT32 file system on the USB
sudo mkfs.vfat /dev/${USB}1
# copy the Windows 10 ISO to the USB
sudo rm -rf /mnt/usb
sudo rm -rf /mnt/iso
sudo mkdir /mnt/iso /mnt/usb
sudo mount ~/Downloads/Win10_1709_EnglishInternational_x64.iso /mnt/iso
sudo mount /dev/${USB}1 /mnt/usb
sudo cp -dR --preserve=all --no-preserve=ownership /mnt/iso/* /mnt/usb
sudo sync
sudo sync
sudo umount /mnt/iso /mnt/usb
sudo rmdir /mnt/iso /mnt/usb





4. Boot from 'Windows 10 installation and repair' USB
REM choose 'Time and currency format'
REM select next
REM click 'Repair your computer'
REM click 'Troubleshoot'
REM click 'Advanced options'
REM click 'Command Prompt'
diskpart
list disk
REM select disk number of device (the other will be the USB)
sel disk 0
REM create new EFI partition (size 150MB)
REM if amount of space is not known simply enter 'create part efi' to use all available space
create part efi size=150
format quick fs=fat32
assign
list vol
REM note the drive letter for Wndows (e.g. C:) and the new EFI partition (e.g. F:)
exit
REM install Windows bootloader to new EFI partition
bcdboot C:\Windows /s F: /f UEFI
exit
REM click 'Turn off your PC'

You can now reboot into Windows to view the resized EFI partition or boot from the Ubuntu LiveUSB and install Ubuntu.

To increase the EFI partition when both Windows and Ubuntu or similar are installed use these instructions:

1. Boot from Ubuntu LiveUSB
# assumes Ubuntu partition is automatically loaded under '/media/<user name>/<UUID of Ubuntu partition>' where <user name> will be 'ubuntu' on a LiveUSB
cd /media/$(whoami)/$(blkid | grep ext4 | awk '{print $2}' | sed 's/^UUID="//' | sed 's/"$//')/boot
# save /boot/efi/EFI/ubuntu
sudo mount $(blkid | grep -i "EFI System Partition" | sed 's/:.*//') /mnt
sudo cp -a /mnt/EFI .
sudo umount /mnt
# remove NVRAM entries for Ubuntu and Windows
sudo efibootmgr -b $(efibootmgr -v | grep -i ubuntu | sed 's/\*.*//' | sed 's/Boot//' | head -1) -B
sudo efibootmgr -b $(efibootmgr -v | grep Windows | sed 's/\*.*//' | sed 's/Boot//' | head -1) -B
# delete EFI partition
DISK=$(blkid | grep -i "EFI System Partition" | sed 's/p.*//')
sudo sgdisk --delete=$(sudo gdisk -l ${DISK} | grep -i "EFI System Partition" | awk '{print $1}') ${DISK}
# shrink Ubuntu partition to allocate as new EFI partition
# click 'ignore' for any 'The driver descriptor says the physical block size is 2048 bytes, but Linux says it is 512 bytes' warnings
# for example new EFI partition will be 150MB so shrink Ubuntu partition by 150MB
sudo gparted
# note the amount of free space created

2. Still in Ubuntu create a 'Windows 10 installation and repair' USB
# go to 'https://www.microsoft.com/en-au/software-download/windows10ISO' in a browser
select 'Windows 10' and click 'Confirm'
select 'English International' and click 'Confirm'
select '64-bit Download' and click 'Confirm'
# wait for ISO to download
# confirm ISO has successfully downloaded
ls -ltr ~/Downloads | tail -1
# insert the other USB
USB=$(ll /dev/disk/by-id/ | grep usb | head -1 | sed 's?.*/??')
# unmount any mounted partitions
sudo umount /dev/${USB}*
# initialize the USB
sudo sgdisk -Z /dev/${USB}
# create a single partition on the USB
sudo sgdisk --new=0:0:0 /dev/${USB}
# create a FAT32 file system on the USB
sudo mkfs.vfat /dev/${USB}1
# copy the Windows 10 ISO to the USB
sudo rm -rf /mnt/usb
sudo rm -rf /mnt/iso
sudo mkdir /mnt/iso /mnt/usb
sudo mount ~/Downloads/Win10_1709_EnglishInternational_x64.iso /mnt/iso
sudo mount /dev/${USB}1 /mnt/usb
sudo cp -dR --preserve=all --no-preserve=ownership /mnt/iso/* /mnt/usb
sudo sync
sudo sync
sudo umount /mnt/iso /mnt/usb
sudo rmdir /mnt/iso /mnt/usb

3. Boot from 'Windows 10 installation and repair' USB
REM choose 'Time and currency format'
REM select next
REM click 'Repair your computer'
REM click 'Troubleshoot'
REM click 'Advanced options'
REM click 'Command Prompt'
diskpart
list disk
REM select disk number of device (the other will be the USB)
sel disk 0
REM create new EFI partition (size 150MB)
REM if amount of space is not known simply enter 'create part efi' to use all available space
create part efi size=150
format quick fs=fat32
assign
list vol
REM note the drive letter for Wndows (e.g. C:) and the new EFI partition (e.g. F:)
exit
REM install Windows bootloader to new EFI partition
bcdboot C:\Windows /s F: /f UEFI
exit
REM click 'Turn off your PC'

4. Boot from Ubuntu LiveUSB
# assumes Ubuntu partition is automatically loaded under '/media/<user name>/<UUID of Ubuntu partition>' where <user name> will be 'ubuntu' on a LiveUSB
cd /media/$(whoami)/$(blkid | grep ext4 | awk '{print $2}' | sed 's/^UUID="//' | sed 's/"$//')/boot
# restore /boot/efi/EFI/ubuntu
sudo mount $(blkid | grep -i "EFI System Partition" | sed 's/:.*//') /mnt
sudo cp -a EFI/ubuntu /mnt/EFI
sudo umount /mnt
# add NVRAM entry for Ubuntu
DISK=$(blkid | grep -i "EFI System Partition" | sed 's/p.*//')
sudo efibootmgr -c -d ${DISK} -p $(sudo gdisk -l ${DISK} | grep -i "EFI System Partition" | awk '{print $1}') -l \\EFI\\ubuntu\\shimx64.efi -L ubuntu
# update /etc/fstab
sudo sed -i "s/$(grep '^UUID' ../etc/fstab | grep '/boot/efi' | awk '{print $1}' | sed 's/UUID=//')/$(blkid | grep -i 'EFI System Partition' | awk '{print $2}' | sed 's/"$//' | sed 's/.*"//')/" ../etc/fstab

5. Boot from Ubuntu
# update GRUB if used as a boot loader
sudo update-grub

Note that if a different distro to Ubuntu (or Ubuntu flavour) was previously installed then the above instructions might need to be modified to change the restore from 'EFI/ubuntu' to whatever directory is relevant and to create the label for the NVRAM entry that reflects the distro installed.  

If Ubuntu previously wasn't booting because the EFI partition was too small simply reboot from the Ubuntu LiveUSB and reinstall Ubuntu.

Both sets of instructions can be downloaded from:
Please donate if you find my work useful using the following link http://goo.gl/nXWSGf.



























12 comments:

billP said...

Happy Holidays! Thanks for all the help this year. I look forward to getting the v4.15 up on my T100HA.

Linuxium said...

Thanks. Let's hope 2018 is the year of getting everything working!

Unknown said...

Just tested the bionic on the cube i10/i15 with the 4.15 rc5 Here are the fixes I used
for backlight
for touchscreen
for displaymanager onscreen keyboard
for audio
for bluetooth
for chrome

#apps required for the following
sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y install i965-va-driver-shaders
sudo apt-get -y install h264enc
sudo apt-get -y install x264
sudo apt-get -y install vdpau-va-driver
sudo apt-get -y install libx264-148
sudo apt-get -y install i965-va-driver
sudo apt-get -y install xbacklight
sudo apt-get -y install qtvirtualkeyboard-plugin
sudo apt-get -y install qml-module-qtquick-virtualkeyboard
sudo apt-get -y install xserver-xorg-video-intel
sudo apt-get -y install intel-gpu-tools
sudo apt-get -y install refind
sudo apt-get -y install ibus
sudo apt-get -y install intel-microcode
sudo apt-get -y install apt-get
sudo apt-get -y install net-tools
sudo apt-get -y install build-essential
sudo apt-get -y install apt-file

wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15-rc5/linux-headers-4.15.0-041500rc5_4.15.0-041500rc5.201712240530_all.deb

wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15-rc5/linux-headers-4.15.0-041500rc5-generic_4.15.0-041500rc5.201712240530_amd64.deb

wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.15-rc5/linux-image-4.15.0-041500rc5-generic_4.15.0-041500rc5.201712240530_amd64.deb

dpkg -i linux-headers-4.15.0-041500rc5_4.15.0-041500rc5.201712240530_all.deb linux-headers-4.15.0-041500rc5-generic_4.15.0-041500rc5.201712240530_amd64.deb linux-image-4.15.0-041500rc5-generic_4.15.0-041500rc5.201712240530_amd64.deb

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

dpkg -i google-chrome-stable_current_amd64.deb
sudo apt-get -y -f install


***************Fix for the backlight
Add lines to /etc/initramfs-tools/modules with the name of each module, pwm-lpss and pwm-lpss-platform
sudo update-initramfs -u

***************Fix for the inverse X axis on the touchscreen

git clone https://github.com/hadess/gt9xx
remove the line 299 if (ts->inverted_x)
from goodix.c

make ; make install

cp goodix_backport.ko /lib/modules/4.15.0-041500rc5-generic/kernel/drivers/input/touchscreen/goodix.ko

***************For displaymanager onscreen keyboard & sddm login manager

sudo su -
echo "QT_IM_MODULE=qtvirtualkeyboard" >> /etc/environment

for audio
Add the following to /etc/pulse/daemon.conf
high-priority = yes
nice-level = -15
realtime-scheduling = no

#Copy the two files to /usr/local/bin
mv linuxium-install-UCM-files.sh /usr/local/bin
mv wrapper-linuxium-install-UCM-files.sh /usr/local/bin
cd /usr/local/bin
chmod 755 *.sh
./wrapper-linuxium-install-UCM-files.sh


****************Fix for the bluetooth
sudo su -
git clone https://github.com/hadess/rtl8723bs
cd rtl8723bs
make; make install
cd ..

git clone https://github.com/lwfinger/rtl8723bs_bt
cd rtl8723bs_bt
make install
./start_bt.sh

#I enabled rc.local and just cd rtl8723bs_bt and run ./start_bt.sh :)

***************Fix for chrome
start chrome and goto the url chrome://flags
enable

Override software rendering list
GPU rasterization
TCP Fast Open
Zero-copy rasterizer
Change Number of raster threads to 4
WebRTC H.264 software video encoder/decoder
FontCache scaling
AsyncImageDecoding

# I think that fixes about everyone and turns bionic in to the 6 million dollar make you holla distro for the cubes ;)

HDbullet said...

Hello! thank you for your guides. I have a Trekstor Primebook P14 based on Apollo Lake and I was struggling to boot a lubuntu live USB. By using your respin I solved the issue. Then I installed lubuntu and as expected the entry ubuntu appeared into the uefi boot list together with Windows and with priority 1. But it was not able to boot, jumping directly to the priority 2 (win). The I applied this guide to resize the EFI partition (now is 150 MB) and after restoring the Windows bootloader I reinstalled lubuntu from the live USB. The entry ubuntu appeared again but still the same behavior as before.. Do you have any suggestion?

Linuxium said...

Try making the NVRAM entry point to 'grubx64.efi' and not 'shimx64.efi' as Lubuntu may not install the 'shim' package by default.

HDbullet said...

Thank you for your answer. In the meanwhile I made it work with the Refind method. But when I will have the opportunity I will try following your suggestion. Happy new year!!!!

Linuxium said...

The problem was caused by Lubuntu missing a package I use for my bootscript so I've fixed this in version 8.0.5. You will need to download 'isorespin.sh' again to get this latest version and then respin your Lubuntu ISO and then perform the install.

HDbullet said...

Thank you! I will try in the next installation :-)

Fulch36 said...

Hi! First of all, thank you for your work on this! Without your efforts I never would have got my system to boot at all.

However, 6 months down the line and a kernel update later and I'm running into issues. My machine is an Apollo Lake CPU, iso was respun with appropriate option when first installed, OS is now Lubuntu 18.04 (upgraded from an initial 17.10 install) and after letting apt autoremove do it's thing, I'm now unable to boot. I simply get dropped into a busybox prompt instead of my OS.

I can boot from a live cd and chroot into the OS but attempting to trigger an update-initramfs ends by saying it failed to generate your script. I've checked my fstab and the UUID of the disk it is attempting to boot from is correct. I'm guessing I need to generate a new efi shim?

Any thoughts or tips would be appreciated, would rather not re-install the OS at this point.

Linuxium said...

Try installing the package 'binutils' and then re-running an 'update-initramfs -u' in your 'chroot'.

Fulch36 said...

Thanks for the quick response!

I re-installed binutils but found it didn't make a difference unfortunately. However, I have now got my system booting again!

I feel silly for not mentioning it in my original comment but your script did throw an error about not being able to copy the shim to the relevant folder. I did some digging and found that my EFI partition was not being mounted in the usual '/boot/efi' path. Once I manually mounted it within the chroot and ran 'update-initramfs -u', your script completed successfully and I could boot into Lubuntu again.

Can I just check, is it possible to have shims for multiple kernel versions installed? I'm guessing I could do this manually by letting your script generate the shim for a given kernel and then using efibootmgr to create a new entry for each kernel version?

Linuxium said...

Multiple shims work fine as long as you have the space on your EFI partition. You would have to manually create and manage them and they may get wiped when running 'update-initramfs -u' and so would need recreating each time.

Post a Comment

All comments now moderated so that spam can be deleted.