How to enable a Windows application in WINE to access a Samba share on a NAS (continued)

In a 2016 post ‘How to enable a Windows application in WINE to access a Samba share on a NAS‘ I explained how to mount in Linux a networked SMB shared folder so that a Windows application running via WINE could access the folder as Drive Y: in order to open and save files in it. In that blog post I also listed a couple of Bash scripts to facilitate the mounting and unmounting of the SMB share for the WINEPREFIX used for the Windows application (~/.wine-pdfxve6 in the example I gave for PDF-XChange Editor, Version 6). However, as I have several Windows applications running via WINE on my machines, and I have used a different WINEPREFIX for each of them, I wanted to be able to mount the SMB share for whichever of those applications I happen to be using at the time. Therefore I modified the original Bash scripts as shown below. The Desktop Configuration files (.desktop files) to launch the scripts are essentially the same as in my earlier blog post; I have just removed the references to the specific Windows application. The four modified files are listed below. Obviously change the username, SMB share name and SMB server name to suit your own situation.

1. Bash script ~/mount_bsfnas1_brianfolder_share.sh

#!/bin/bash
mount_share () {
    echo
    echo "Enter your Linux account password below..."
    echo
    sudo ln -s /media/bsfnas1/brianfolder ~/$PREFIX/dosdevices/y:
    sudo mount.cifs //bsfnas1/brianfolder/ -o user=brianfolder,pass=enricocaruso,uid=$(id -u),gid=$(id -g) ~/$PREFIX/dosdevices/y:
}
echo
echo "This will mount the Samba share folder brianfolder on the bsfnas1 machine."
echo
echo
echo "== Select which WINEPREFIX you wish to use =="
echo
ls ~/.wine-* | grep .wine | awk -F'/' '{print NR " " substr($4, 1, length($4)-1)}'
NUMPREFIXES=$(ls ~/.wine-* | grep .wine | wc -l)
echo
read -p "Enter number (q to abort) and press ENTER: " CHOICE
if [ "$CHOICE" != "q" ] && [ "$CHOICE" -gt 0 ] && [ "$CHOICE" -le $NUMPREFIXES ]; then
    PREFIX=$(ls ~/.wine-* | grep .wine | awk -F'/' '{print NR " " substr($4, 1, length($4)-1)}' | grep "$CHOICE " | awk -F' ' '{print $2}')
    echo
    if [ ! -e ~/$PREFIX/dosdevices/y: ]; then
        mount_share
    else
        echo -n "~/$PREFIX/dosdevices/y: already exists. Is it OK to proceed anyway (y/n)? "
        read ANSWER
        if [ $ANSWER = "y" ]; then
            rm ~/$PREFIX/dosdevices/y:
            mount_share
        fi
    fi
    echo
fi
if grep -q "/media/bsfnas1/brianfolder" /proc/mounts; then
    echo "Samba share //bsfnas1/brianfolder is mounted for WINEPREFIX ~/$PREFIX ."
else
    echo "Samba share //bsfnas1/brianfolder is not mounted."
fi
echo
echo "You may now close this window."
read ANSWER
exit

2. Bash script ~/umount_bsfnas1_brianfolder_share.sh

#!/bin/bash
echo
echo "This will unmount the Samba share folder brianfolder on the bsfnas1 machine."
echo
echo "Enter your Linux account password below..."
echo
sudo umount ~/.wine-*/dosdevices/y: 2>/dev/null
echo
if grep -q "/media/bsfnas1/brianfolder" /proc/mounts; then
  echo "Samba share //bsfnas1/brianfolder is mounted."
else
  echo "Samba share //bsfnas1/brianfolder is not mounted."
fi
echo
echo "You may now close this window."
exit

3. Desktop Configuration file ~/Desktop/mount_bsfnas1_brianfolder_share.desktop

[Desktop Entry]
Comment[en_GB]=Mount bsfnas1 brianfolder share for current WINEPREFIX
Comment=Mount bsfnas1 brianfolder share for current WINEPREFIX
Exec=sh /home/fitzcarraldo/mount_bsfnas1_brianfolder_share.sh
GenericName[en_GB]=Mount bsfnas1 brianfolder share for current WINEPREFIX
GenericName=Mount bsfnas1 brianfolder share for current WINEPREFIX
Icon=media-mount
MimeType=
Name[en_GB]=mount_bsfnas1_brianfolder_share
Name=mount_bsfnas1_brianfolder_share
Path=
StartupNotify=true
Terminal=true
TerminalOptions=\s--noclose
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=fitzcarraldo

4. Desktop Configuration file ~/Desktop/umount_bsfnas1_brianfolder_share.desktop

[Desktop Entry]
Comment[en_GB]=Unmount bsfnas1 brianfolder share for current WINEPREFIX
Comment=Unmount bsfnas1 brianfolder share for current WINEPREFIX
Exec=sh /home/fitzcarraldo/umount_bsfnas1_brianfolder_share.sh
GenericName[en_GB]=Unmount bsfnas1 brianfolder share for current WINEPREFIX
GenericName=Unmount bsfnas1 brianfolder share for current WINEPREFIX
Icon=media-eject
MimeType=
Name[en_GB]=umount_bsfnas1_brianfolder_share
Name=umount_bsfnas1_brianfolder_share
Path=
StartupNotify=true
Terminal=true
TerminalOptions=\s--noclose
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=fitzcarraldo

Now when I double-click on the icon to mount the SMB share for a Windows application running via WINE, a terminal window pops up displaying the WINEPREFIXs currently installed on my machine:


This will mount the Samba share folder brianfolder on the bsfnas1 machine.


== Select which WINEPREFIX you wish to use ==

1 .wine-3dimviewer
2 .wine-myphoneexplorer
3 .wine-nbtscan
4 .wine-pdfxve6
5 .wine-PortableApps
6 .wine-radiant
7 .wine-symmetry
8 .wine-visio
9 .wine-xnviewmp

Enter number (q to abort) and press ENTER: 

Let’s say I want to use the Windows application XnViewMP. I would enter ‘9’ and press ‘Enter’. The rest of the interaction should be obvious:


This will mount the Samba share folder brianfolder on the bsfnas1 machine.


== Select which WINEPREFIX you wish to use ==

1 .wine-3dimviewer
2 .wine-myphoneexplorer
3 .wine-nbtscan
4 .wine-pdfxve6
5 .wine-PortableApps
6 .wine-radiant
7 .wine-symmetry
8 .wine-visio
9 .wine-xnviewmp

Enter number (q to abort) and press ENTER: 9

~/.wine-xnviewmp/dosdevices/y: already exists. Is it OK to proceed anyway (y/n)? y

Enter your Linux account password below...

[sudo] password for fitzcarraldo: 

Samba share //bsfnas1/brianfolder is mounted for WINEPREFIX ~/.wine-xnviewmp .

You may now close this window.

Henceforth the Windows application XnViewMP will be able to access the Y: drive which is actually the SMB share //bsfnas1/brianfolder.

Once I have finished using the application, I just double-click on the the icon to unmount the SMB share, and a terminal window pops up displaying the following:


This will unmount the Samba share folder brianfolder on the bsfnas1 machine.

Enter your Linux account password below...

[sudo] password for fitzcarraldo: 

Samba share //bsfnas1/brianfolder is not mounted.

You may now close this window.

Once I have entered my Linux password for the local machine, the script will unmount the SMB share and the terminal window will close automatically if you have configured the Desktop Configuration file by right-clicking on the icon and unticking ‘Do not close when command exits’ in KDE, ‘Keep terminal window open after command execution’ in LXDE, or similar in other desktop environments.

Note: If you use Microsoft Office via WINE, you also might be interested in a comment on my earlier blog post about a Microsoft Office problem in saving files to a remote SMB share.

HEIC image files in Linux

I was at an event recently where the attendees were asked to upload their camera and smartphone photos and videos to a shared Google Drive folder. Some of the uploaded photo files have a .HEIC (High Efficiency Image Container) extension, which I had not come across before. I have since learnt that these HEIC files were produced by iPhones running iOS 11, encoded using the HEIF (High Efficiency Image File) format. Apparently the HEIF format is superior to the JPEG format in a number of ways (see the links at the end of my post, especially the image examples given by Nokia), although it is subject to patents and therefore I believe there are certain constraints to coding image files in HEIC format. Anyway, I’ll leave you to read the fine print. My interest was simply because I wanted to be able to download the above-mentioned photo files and view them all in the file managers and image-viewing applications in Linux and Android on my various devices.

Now, I can browse and view the above-mentioned shared HEIC images in Google Drive in the Firefox and Chrome browsers in Linux, although an ownCloud site viewed using the same browsers displays the HEIC files as grey icons that can only be downloaded, not opened and viewed in the browser. I also found that Cirrus, the Android app for ownCloud that I use on my Galaxy Note 8 phone, cannot display HEIC photos either.

I downloaded the HEIC files to a machine running Lubuntu 18.04 and to a machine running Gentoo Linux. The file manager PCManFM in Lubuntu 18.04 displays grey icons rather than thumbnails for these HEIC files, and KDE’s Dolphin 18.08.3 file manager in Gentoo Linux displays green image icons rather than thumbnails for them. As far as Linux image viewers go, in Lubuntu 18.04 I find that GPicView 0.2.5 and Geeqie 1.4 cannot display HEIC images, and in Gentoo Linux KDE I find that GQview 2.1.5-r1, Okular 18.08.3 and Gwenview 18.08.3 cannot display HEIC images. So I set about converting all the HEIC files to JPG files. I managed to do this but needed to use a range of tools, as illustrated by a couple of examples below for Lubuntu 18.04 and Gentoo Linux. This post might seem long-winded but perhaps may be of help to Linux users coming across .HEIC files for the first time.

From the .HEIC files I had downloaded I picked one at random to try and convert to a JPG file: IMG_3706.HEIC. Its EXIF data confirms it is an HEIC file:

user $ exiftool IMG_3706.HEIC | grep "File Type"
File Type                       : HEIC
File Type Extension             : heic
user $ exiftool IMG_3706.HEIC | grep "Camera Model"
Camera Model Name               : iPhone 7 Plus

Several of the files with the .HEIC suffix that I downloaded were not real HEIC files according to their EXIF data:

user $ exiftool IMG_9474.HEIC | grep "File Type"
File Type                       : JPEG
File Type Extension             : jpg
user $ exiftool IMG_9474.HEIC | grep "Camera Model"
Camera Model Name               : iPhone 8

Those files were apparently treated as JPEG files by the tools I mention below, so I have omitted the results for those ‘false’ HEIC files.

Lubuntu 18.04

1. I installed the libheif example tools:

user $ sudo apt install libheif-examples

2. I used the heif-info command to check the file:

user $ heif-info IMG_3706.HEIC 
image: 3024x4032 (id=49), primary
  thumbnail: 240x320
  alpha channel: no
  depth channel: no

3. I tried to convert the file using the heif-convert command:

user $ heif-convert IMG_3706.HEIC IMG_3706.jpg
File contains 1 images
Written to IMG_3706.jpg

4. Apparently Imagemagick >=7.0.7-22 compiled with --with-libheif is supposed to be able to convert HEIC files to JPG. Anyway, I tried to convert the file using the current version of Imagemagick in Lubuntu 18.04 (the current package version is 8:6.9.7.4+dfsg-16ubuntu6.4):

user $ convert IMG_3706.HEIC IMG_3706a.jpg
convert-im6.q16: no decode delegate for this image format `HEIC' @ error/constitute.c/ReadImage/504.
convert-im6.q16: no images defined `IMG_3706a.jpg' @ error/convert.c/ConvertImageCommand/3258.

5. Apparently the GIMP >=2.10.2 supports HEIF by using heif-gimp-plugin. Anyway, I tried to open the file with the current version of the GIMP in Lubuntu 18.04 (the current package version is 2.8.22-1). The GIMP launches and pops-up a window with the title ‘GIMP Message’ containing the following message and an ‘OK’ button:

GIMP Message
Opening /home/fitzcarraldo/IMG_3706.HEIC’ failed: Unknown file type

6. I used the online tool ‘libheif decoder demo’ (https://strukturag.github.io/libheif/) in a browser window. This can load the file IMG_3706.HEIC (‘Browse…’ button) and convert it (‘Save image…’ button) to IMG_3706.jpeg.

Gentoo Linux with KDE 5

1. I installed the libheif example tools implicitly by re-merging Imagemagick with USE="heif", which installs libheif.

root # cat /etc/portage/package.use/imagemagick 
media-gfx/imagemagick heif
root # emerge imagemagick

2. I used the heif-info command to check the file:

user $ heif-info IMG_3706.HEIC  
image: 3024x4032 (id=49), primary
  thumbnail: 240x320
  alpha channel: no
  depth channel: no

3. I tried to convert the file using the heif-convert command:

user $ heif-convert IMG_3706.HEIC IMG_3706.jpg
File contains 1 images
Written to IMG_3706.jpg

4. I tried to convert the file using Imagemagick >=7.0.7-22 compiled with --with-libheif (Imagemagick merged with USE="heif"):

user $ convert IMG_3706.HEIC IMG_3706a.jpg
user $

So Imagemagick 7.0.8.16 in Gentoo has no trouble with the file IMG_3706.HEIC.

5. I tried to open the file with the GIMP >=2.10.2, which supports HEIF using heif-gimp-plugin (GIMP >=2.10.6-r1 with USE="heif" in the case of Gentoo Linux)

First I re-merged the GIMP with the heif USE flag:

root # cat /etc/portage/package.accept_keywords/gimp
=media-gfx/gimp-2.10.8-r1 ~amd64
# required by media-gfx/gimp-2.10.8-r1::gentoo
=media-libs/libmypaint-1.3.0 ~amd64
# required by media-gfx/gimp-2.10.8-r1::gentoo
=media-gfx/mypaint-brushes-1.3.0-r1 ~amd64
# required by media-gfx/gimp-2.10.8-r1::gentoo
=media-libs/gegl-0.4.12 ~amd64
# required by media-gfx/gimp-2.10.8-r1::gentoo
=media-libs/babl-0.1.60 ~amd64
root # cat /etc/portage/package.use/gimp
media-gfx/gimp heif
root # emerge -1vp gimp

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N    ~] media-gfx/mypaint-brushes-1.3.0-r1:1.0::gentoo  2,390 KiB
[ebuild     U ~] media-libs/babl-0.1.60::gentoo [0.1.38::gentoo] USE="(-altivec)" CPU_FLAGS_X86="mmx sse sse2 sse3%* sse4_1 -f16c" 670 KiB
[ebuild  N     ] media-libs/gexiv2-0.10.8::gentoo  USE="-introspection -python -static-libs -test -vala" PYTHON_TARGETS="python2_7 python3_6 -python3_4 -python3_5" 620 KiB
[ebuild  NS   ~] media-libs/gegl-0.4.12:0.4::gentoo [0.2.0-r5:0::gentoo] USE="cairo ffmpeg introspection lcms openexr sdl svg tiff v4l -debug -jpeg2k -lensfun -libav -raw -test -umfpack -vala -webp" CPU_FLAGS_X86="mmx sse" 6,900 KiB
[ebuild  NS    ] media-libs/gegl-0.3.26:0.3::gentoo [0.2.0-r5:0::gentoo] USE="cairo ffmpeg introspection lcms openexr sdl svg tiff v4l -debug -jpeg2k -lensfun -raw -test -umfpack -vala -webp" CPU_FLAGS_X86="mmx sse" 6,378 KiB
[ebuild  N    ~] media-libs/libmypaint-1.3.0::gentoo  USE="gegl nls openmp -introspection" 428 KiB
[ebuild     U ~] media-gfx/gimp-2.10.8-r1:2::gentoo [2.8.22-r1:2::gentoo] USE="alsa heif%* mng openexr%* udev wmf -aalib (-altivec) (-aqua) -debug -doc -gnome -jpeg2k -postscript -python -smp -test -unwind% -vector-icons% -webp% -xpm (-bzip2%*) (-curl%) (-dbus%*) (-exif%*) (-jpeg%*) (-lcms%*) (-pdf%*) (-png%*) (-svg%*) (-tiff%*)" CPU_FLAGS_X86="mmx sse" PYTHON_TARGETS="python2_7" 31,206 KiB

Total: 7 packages (2 upgrades, 3 new, 2 in new slots), Size of downloads: 48,591 KiB

I then launched the GIMP and successfully opened the file IMG_3706.HEIC, and I was able to export it as IMG_3706.jpg.

6. As would be expected, the online tool ‘libheif decoder demo’ (https://strukturag.github.io/libheif/) behaves exactly the same in Gentoo Linux as it does in Lubuntu 18.04 (see earlier).

Summary

So there you have it; if the Linux file manager and/or image viewing applications you use cannot already handle HEIC files, the tools in Linux that I found may work are as follows:

  • heif-convert (from the package libheif-examples in Ubuntu/Lubuntu, or from from the package libheif in Gentoo).
  • Imagemagick (not every version).
  • The GIMP (not every version).
  • the online tool ‘libheif decoder demo’ (https://strukturag.github.io/libheif/).

I have not tried the copyright open-source code from Nokia (see link under Further Reading below), qt-heif-image-plugin and tifig (not in active development). If you have had success using another tool to convert HEIC files, please post a comment below for the benefit of other users, giving the name of the tool, the package name and version, and the Linux distribution (including release number, if not a rolling distribution).

Further reading

  1. Wikipedia – High Efficiency Image File Format
  2. Lifewire – What Are HEIF and HEIC, and Why Is Apple Using Them?
  3. Nokia – High Efficiency Image File Format (HEIF)
  4. libheif – a ISO/IEC 23008-12:2017 HEIF file format decoder and encoder
  5. askubuntu – Any app on Ubuntu to open HEIF (.heic, High Efficiency Image File Format) pictures?

Configuring Lubuntu 18.04 to enable hibernation using a swap file

In an earlier post about Lubuntu 18.04 I stated that hibernation is precluded because the Lubuntu Installer installs the OS with a swap file instead of a swap partition. In fact, even with a swap file it is possible to configure Lubuntu so that hibernation is possible. This is how I did it.

1.  This PC has 4 GiB RAM but the Lubuntu Installer had created a 2 GiB swap file named /swapfile, so I increased the size of the swap file to 4 GiB to ensure it was large enough to store the memory image:

user $ sudo swapoff -a
user $ sudo dd if=/dev/zero of=/swapfile bs=1024 count=4M
user $ sudo chmod 600 /swapfile
user $ sudo mkswap /swapfile
user $ sudo swapoff -a
user $ sudo swapon /swapfile
user $ cat /proc/meminfo | grep -i memtotal
MemTotal:        3924108 kB
user $ ls -la /swapfile
-rw------- 1 root root 4294967296 Jul 10 18:25 /swapfile

Note that you can check the status of the swap file before and after the above steps by using either of the following commands:

user $ swapon -s
user $ free -m

2.  The Lubuntu Installer had previously configured /etc/fstab for the swap file, so I left that as it is:

user $ grep swapfile /etc/fstab
/swapfile                                 none            swap    sw              0       0

3.  I checked on which device the root partition with the file /swapfile is located (sda2 in my case) and found out its UUID (ignore the PARTUUID):

user $ sudo blkid
[sudo] password for fitzcarraldo:
/dev/sda1: UUID="3602-BD57" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="72b3693e-b81f-7299-84fb-bf3781bef43d"
/dev/sda2: UUID="afe17116-26fa-4169-b2d9-fb6ac8afc63c" TYPE="ext4" PARTUUID="738fed17-293d-832f-c7a4-e83471fe8ca6"

4.  I found the resume_offset for the file /swapfile, which is 16746496 in my case (look for the first value in the two columns under ‘physical_offset‘):

user $ sudo filefrag -v /swapfile
Filesystem type is: ef53
File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   30719:   16746496..  16777215:  30720:            
   1:    30720..   63487:   16809984..  16842751:  32768:   16777216:
   2:    63488..   96255:   16842752..  16875519:  32768:            
   3:    96256..  126975:   16875520..  16906239:  30720:            
   4:   126976..  129023:   16908288..  16910335:   2048:   16906240:
   5:   129024..  161791:   16912384..  16945151:  32768:   16910336:
   6:   161792..  194559:   16945152..  16977919:  32768:            
   7:   194560..  227327:   16977920..  17010687:  32768:            
   8:   227328..  249855:   17010688..  17033215:  22528:            
   9:   249856..  282623:   17035264..  17068031:  32768:   17033216:
  10:   282624..  315391:   17068032..  17100799:  32768:            
  11:   315392..  319487:   17100800..  17104895:   4096:            
  12:   319488..  321535:   17121280..  17123327:   2048:   17104896:
  13:   321536..  325631:   17129472..  17133567:   4096:   17123328:
  14:   325632..  327679:   17137664..  17139711:   2048:   17133568:
  15:   327680..  329727:   17143808..  17145855:   2048:   17139712:
  16:   329728..  331775:   17154048..  17156095:   2048:   17145856:
  17:   331776..  339967:   17162240..  17170431:   8192:   17156096:
  18:   339968..  344063:   24485888..  24489983:   4096:   17170432:
  19:   344064..  346111:   32665600..  32667647:   2048:   24489984:
  20:   346112..  348159:   32677888..  32679935:   2048:   32667648:
  21:   348160..  350207:   33261568..  33263615:   2048:   32679936:
  22:   350208..  352255:   33363968..  33366015:   2048:   33263616:
  23:   352256..  354303:   33853440..  33855487:   2048:   33366016:
  24:   354304..  356351:   34000896..  34002943:   2048:   33855488:
  25:   356352..  389119:   34027520..  34060287:  32768:   34002944:
  26:   389120..  391167:   34060288..  34062335:   2048:            
  27:   391168..  393215:   34134016..  34136063:   2048:   34062336:
  28:   393216..  395263:   34158592..  34160639:   2048:   34136064:
  29:   395264..  428031:   34189312..  34222079:  32768:   34160640:
  30:   428032..  452607:   34222080..  34246655:  24576:            
  31:   452608..  485375:   34248704..  34281471:  32768:   34246656:
  32:   485376..  518143:   34281472..  34314239:  32768:            
  33:   518144..  550911:   34314240..  34347007:  32768:            
  34:   550912..  583679:   34347008..  34379775:  32768:            
  35:   583680..  616447:   34379776..  34412543:  32768:            
  36:   616448..  643071:   34412544..  34439167:  26624:            
  37:   643072..  645119:   34445312..  34447359:   2048:   34439168:
  38:   645120..  649215:   34457600..  34461695:   4096:   34447360:
  39:   649216..  659455:   34463744..  34473983:  10240:   34461696:
  40:   659456..  688127:   34476032..  34504703:  28672:   34473984:
  41:   688128..  690175:   34506752..  34508799:   2048:   34504704:
  42:   690176..  692223:   34510848..  34512895:   2048:   34508800:
  43:   692224..  724991:   34514944..  34547711:  32768:   34512896:
  44:   724992..  757759:   34549760..  34582527:  32768:   34547712:
  45:   757760..  778239:   34582528..  34603007:  20480:            
  46:   778240..  786431:   34637824..  34646015:   8192:   34603008:
  47:   786432..  819199:   34648064..  34680831:  32768:   34646016:
  48:   819200..  843775:   34680832..  34705407:  24576:            
  49:   843776..  845823:   34707456..  34709503:   2048:   34705408:
  50:   845824..  849919:   34713600..  34717695:   4096:   34709504:
  51:   849920..  854015:   34729984..  34734079:   4096:   34717696:
  52:   854016..  886783:   34744320..  34777087:  32768:   34734080:
  53:   886784..  919551:   34777088..  34809855:  32768:            
  54:   919552..  950271:   34809856..  34840575:  30720:            
  55:   950272..  983039:   34842624..  34875391:  32768:   34840576:
  56:   983040.. 1015807:   34875392..  34908159:  32768:            
  57:  1015808.. 1048575:   34908160..  34940927:  32768:             last,eof
/swapfile: 38 extents found

Note that you can also find the resume_offset by installing the package uswsusp and using the command swap-offset on the swap file:

user $ sudo apt install uswsusp
user $ sudo swap-offset /swapfile
resume offset = 16746496

5.  I updated the file /boot/grub/grub.cfg using the information found in Steps 3 & 4 as follows:

5.1  I added ‘resume=UUID=afe17116-26fa-4169-b2d9-fb6ac8afc63c resume_offset=16746496 resumedelay=15‘ to the parameters in the variable GRUB_CMDLINE_LINUX_DEFAULT in the file /etc/default/grub (Your existing parameters could be different to mine; that is not a problem):

user $ sudo nano /etc/default/grub
#
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi_backlight=vendor acpi_osi='!Windows 2013' acpi_osi='!Windows 2012' resume=UUID=afe17116-26fa-4169-b2d9-fb6ac8afc63c resume_offset=16746496 resumedelay=15"
#

Note that the optional ‘resumedelay=15‘ specifies the delay (in seconds) to pause before attempting to read the resume files. I added this to try to allow enough time for the filesystem containing the swap file to become Read-Write.

5.2  I regenerated /boot/grub/grub.cfg by using the following command:

user $ sudo update-grub

6.  I edited the file /etc/initramfs-tools/conf.d/resume using the information found in Steps 3 & 4, and regenerated the initramfs files for the kernel images in the /boot directory:

user $ sudo nano /etc/initramfs-tools/conf.d/resume
RESUME=UUID=afe17116-26fa-4169-b2d9-fb6ac8afc63c resume_offset=16746496
# Resume from /swapfile
user $ sudo update-initramfs -u -k all

7.  I edited the Polkit rules files to permit hibernation (Create the files if they do not already exist):

7.1  For Polkit version 0.106 and higher

user $ sudo nano /etc/polkit-1/rules.d/85-suspend.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.login1.suspend" ||
        action.id == "org.freedesktop.login1.suspend-multiple-sessions" ||
        action.id == "org.freedesktop.login1.hibernate" ||
        action.id == "org.freedesktop.login1.hibernate-multiple-sessions")
    {
        return polkit.Result.YES;
    }
});

7.2  For Polkit versions below 0.106

user $ sudo nano /var/lib/polkit-1/localauthority/50-local.d/50-enable-suspend-on-lockscreen.pkla
[Allow hibernation and suspending with lock screen]
Identity=unix-user:*
Action=org.freedesktop.login1.suspend;org.freedesktop.login1.suspend-multiple-sessions;org.freedesktop.login1.hibernate;org.freedesktop.login1.hibernate-multiple-sessions
ResultAny=yes
ResultInactive=yes
ResultActive=yes

It does not do any harm to create both the above-mentioned rules files, whatever the version of Polkit that happens to be installed.

8.  I rebooted, logged in, launched a few GUI applications and then clicked on the Lubuntu menu icon on the Panel and selected ‘Logout’ > ‘Hibernate’, which did put the machine into hibernation. I then pressed the PC’s power push-button to resume from disk, entered my password on the lock screen and the Desktop appeared exactly as it was prior to hibernation. All good.

Lubuntu 18.04 ‘Gave up waiting for suspend/resume device’

Software Updater in Lubuntu 17.10 recently prompted me to upgrade the OS to 18.04 LTS, and I clicked on ‘Yes, Upgrade Now’. The upgrade was performed and I was able to boot the PC into 18.04, login and access the Desktop as usual. However, I noticed a new message ‘Gave up waiting for suspend/resume device‘ was displayed on TTY1.

Now, I recalled that the Lubuntu 17.10 Installer had created a swap file rather than a swap partition when I installed Lubuntu, as confirmed in the output listed below:

user $ sudo blkid
[sudo] password for fitzcarraldo: 
/dev/sda1: UUID="3602-BD57" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="72b3693e-b81f-7299-84fb-bf3781bef43d"
/dev/sda2: UUID="afe17116-26fa-4169-b2d9-fb6ac8afc63c" TYPE="ext4" PARTUUID="738fed17-293d-832f-c7a4-e83471fe8ca6"
user $ swapon
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2
user $ ls /swapfile 
/swapfile

The initramfs installed by upgrading to Lubuntu 18.04 expects a swap partition in order to resume from hibernation:

user $ lsinitramfs /initrd.img | grep resume
scripts/local-premount/resume
bin/resume
conf/conf.d/resume

And, when I regenerated the initramfs files for the three kernel images in the /boot directory, I could see from the terminal output that the update-initramfs tool was expecting a swap partition:

user $ sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-4.15.0-23-generic
W: initramfs-tools configuration sets RESUME=UUID=7b4cb3c5-4c17-42ae-be3c-cc35d31fe287
W: but no matching swap device is available.
update-initramfs: Generating /boot/initrd.img-4.15.0-22-generic
W: initramfs-tools configuration sets RESUME=UUID=7b4cb3c5-4c17-42ae-be3c-cc35d31fe287
W: but no matching swap device is available.
update-initramfs: Generating /boot/initrd.img-4.13.0-43-generic
W: initramfs-tools configuration sets RESUME=UUID=7b4cb3c5-4c17-42ae-be3c-cc35d31fe287
W: but no matching swap device is available.

I had a look in the file /etc/initramfs-tools/conf.d/resume and found that it had indeed been configured to expect a swap partition, although I have no idea where that UUID came from, as it was not for any of the partitions on this PC:

user $ cat /etc/initramfs-tools/conf.d/resume
RESUME=UUID=7b4cb3c5-4c17-42ae-be3c-cc35d31fe287

So I edited the contents of the configuration file to point to the swap file /swapfile instead of a non-existent partition:

user $ cat /etc/initramfs-tools/conf.d/resume
#RESUME=UUID=7b4cb3c5-4c17-42ae-be3c-cc35d31fe287
RESUME=/swapfile

Then I regenerated the initramfs files for the three kernel images currently in /boot on the PC:

user $ sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-4.15.0-23-generic
update-initramfs: Generating /boot/initrd.img-4.15.0-22-generic
update-initramfs: Generating /boot/initrd.img-4.13.0-43-generic

As you can see above, there were no longer any messages that ‘no matching swap device is available‘. And, when I rebooted the PC, the message ‘Gave up waiting for suspend/resume device‘ was no longer displayed on TTY1. All good again, although it’s a pity the Lubuntu Installer did not create a swap partition so that the installation could be put into hibernation. With a swap file, hibernation is not possible.

Update (14 July 2018): Actually, it is possible to hibernate if the installation has a swap file instead of a swap partition – see my latest post: Configuring Lubuntu 18.04 to enable hibernation using a swap file.

Partitioning hard disk drives for BIOS-MBR, BIOS-GPT and UEFI-GPT in Linux

Introduction

This post was prompted by recent threads in the Gentoo Linux Forums such as the following:

  • partition MBR/GPT fdisk question‘ in which two people asked how to partition a HDD using GPT. One has a computer that only has BIOS firmware; the other has a computer with firmware that supports UEFI and BIOS (user-selectable) and who apparently wanted to boot using BIOS.
  • [SOLVED] installing on UEFI system‘ in which someone asked how to partition a HDD for a computer with UEFI firmware.

These Gentoo Linux users were confused by the instructions in the Gentoo Installation Guide – Preparing the disks. In my opinion the Gentoo Installation Guide is confusing. You do not need a BIOS boot partition (Code EF02) if you want to use a GPT-partitioned HDD with a UEFI computer; you only need a BIOS boot partition on a GPT-partitioned HDD if you want to use it with a BIOS computer. You do not need an ESP (EFI System Partition) if you want to use a GPT-partitioned HDD with a BIOS computer; you only need an ESP (Code EF00) — which must be formatted as FAT32 — if you want to use UEFI.

Coincidentally, recently an Ubuntu user also told me he finds GPT partitioning for UEFI confusing.

So, in the hope of helping people having trouble understanding how to partition a HDD for Linux, I decided to post some information on the two firmware designs and the two partitioning designs, plus list a few (of the many) partitioning schemes that can be used. The purpose of this post is to provide an overview of the designs and possible schemes, not to explain how to use the various partitioning tools or to list the precise steps you must follow. I have tried to avoid going into fine detail (for example the oft-quoted limit of 2TiB for MBR-partitioned HDDs is contigent on 512B sectors).

Firstly, let’s get the terminology straight: you should say ‘UEFI firmware’, not ‘UEFI BIOS’. The latter is an oxymoron. I know that some computer manufacturers and third-party firmware providers use the term ‘UEFI BIOS’, but it is incorrect. The ‘BIOS’ (a.k.a. ‘PC BIOS’) and the UEFI are two different designs of firmware used during the booting process. BIOS firmware and MBR partitioning are older (‘legacy’) designs; UEFI firmware and GPT partitioning are the latest designs, intended to replace BIOS and MBR. See the end of this post for links to articles regarding BIOS, MBR, UEFI and GPT that I recommend you also read.

I personally have not come across computers that support solely UEFI; all the computers I have used allow the user to configure the firmware at boot via the Setup menu to use either UEFI or BIOS. Some UEFI firmware manufacturers show the BIOS support option in the Setup menu as ‘Compatibility Support Module’ (CSM) or ‘Legacy Mode’.

‘Secure Boot’ is one of the touted UEFI features not present in BIOS. Linux expert Roderick W. Smith explains Secure Boot in his article ‘Linux on UEFI: A Quick Installation Guide‘:

One optional feature of UEFI deserves mention: Secure Boot. This feature is designed to minimize the risk of a computer becoming infected with a boot kit, which is a type of malware that infects the computer’s boot loader. Boot kits can be particularly difficult to detect and remove, which makes blocking them a priority. Microsoft requires that all desktop and laptop computers that bear a Windows 8 logo ship with Secure Boot enabled. This type of configuration complicates Linux installation, although some distributions handle this problem better than do others. Do not confuse Secure Boot with EFI or UEFI, though; it’s possible for an EFI computer to not support Secure Boot, and it’s possible to disable Secure Boot even on x86-64 EFI computers that support it. Microsoft requires that users can disable Secure Boot for Windows 8 certification on x86 and x86-64 computers; however, this requirement is reversed for ARM computers—such computers that ship with Windows 8 must not permit the user to disable Secure Boot. Fortunately, ARM-based Windows 8 computers are currently rare. I recommend avoiding them.

GPT-partitioned HDDs have become the norm these days for two principal reasons:

  • the MBR design limits the amount of disk space accessible to a maximum of 2TiB but HDDs larger than 2TiB are now common;
  • Microsoft has standardised on UEFI, and UEFI will not boot an MBR-partitioned HDD (Section 5.2.1 of Version 2.6 of the UEFI Specification specifies that UEFI firmware shall not execute the boot code in an MBR located at the first logical block of a disk with the MBR disk layout).

The ‘Protective MBR’ at the beginning of every GPT-partitioned disk (in the same location on the disk as a legacy MBR would be) is designed to prevent MBR-based disk utilities misrecognising and possibly overwriting GPT-partitioned disks. A fake (i.e. it does not really exist) single partition called the ‘GPT Protective Partition’ (Code EE00) is specified in the Protective MBR to occupy as much of the drive as can be represented in an MBR, namely a maximum of 2TiB in the case of a disk with 512B sectors. Operating systems and tools not designed for GPT disks will read the Protective MBR and detect that the disk contains a single partition of unknown type and with no empty space, and will refuse to modify the disk unless the user deletes this partition. This design (i.e. the Protective MBR and GPT Protective Partition) was devised in order to minimise the possibility of a) legacy software accidentally overwriting a GPT-partitioned HDD; b) GPT-aware software accidentally overwriting an MBR-partitioned HDD (the absence of a partition of type EEh defined in the Protective MBR would indicate to GPT-aware operating systems and tools that the HDD is not GPT-partitioned).

You can use an MBR-partitioned HDD with BIOS; you can use a GPT-partitioned HDD with BIOS; you can use a GPT-partitioned HDD with UEFI; you cannot use an MBR-partitioned HDD with UEFI. If the firmware in your computer has an option to select BIOS mode (some firmware manufacturers refer to this as ‘Compatibility Support Module’ or ‘Legacy Mode’) instead of UEFI and you want to use an MBR on the HDD, you will have to use BIOS. In summary, for Linux your options are BIOS-MBR, BIOS-GPT or UEFI-GPT. I will discuss these three options and provide some possible partitioning schemes in each case.

The layout of a GPT-partitioned HDD is as follows:

The beginning of a GPT-partitioned disk
Protective MBR 512B
Primary GPT Header 512B
Primary Partition Table entries Up to 16KiB (maximum of 128 partitions)

Therefore the unpartitioned space at the beginning of the HDD should be at least 17KiB.

Unlike in the MBR design, the end of a GPT-partitioned disk stores a backup of the partition table:

The end of a GPT-partitioned disk
Secondary Partition Table entries Up to 16KiB (maximum of 128 partitions)
Secondary GPT Header 512B

(The Secondary GPT Header really does come after the Secondary Partition Table entries.)

Therefore the upartitioned space at end of a GPT-partitioned disk should be at least 16.5KiB.

The partitions themselves are located between the Primary GPT and the Secondary GPT, i.e. between the above two tables.

The remainder of a GPT-partitioned disk between the above two areas can contain up to 128 partitions. One partition — normally the first partition is used — must be the ‘ESP’ (EFI System Partition), which should be formatted as FAT32 and have the ‘esp’ and ‘boot’ flags set. The partition code must be EF02. The minimum possible size of a FAT32 partition is 33,549,824B (~32MiB) with 65525 clusters and 512 byte sectors, or 268,398,592B (~256MiB) with 65525 clusters and 4KiB sectors. The required size of the ESP will depend on what is stored in it (for example the now-orphaned ELILO boot loader stored the Linux kernel images in it, whereas the GRUB boot loader does not). The Ubuntu Community Help Wiki specifies a minimum of 100MiB and recommends 200MiB. The Gentoo Installation Guide recommends 128MB.

The versions of GParted and KDE Partition Manager I have used to partition HDDs seem to want to reserve at least 2048 512B sectors of empty space before the first partition (sometimes these two utilities force me to have 4096 512B sectors of empty space before the first partition), so I suggest leaving at least 1MiB of unpartitioned space at the beginning and end of the HDD if you want to partition a disk for GPT using those tools. Actually, for peace of mind you may as well leave 1MiB of empty space at the beginning and end of the disk whatever GUI tools or console commands (parted, fdisk, gdisk, etc.) you use to partition the disk.

By the way, if you wanted to use MBR instead of GPT, the MBR (512B) plus the GRUB embedding area after the MBR (~31KiB) means that 1MiB would also be more than enough for an MBR HDD (see GNU GRUB Manual – 3.4 BIOS installation).

Thus my suggestions for HDD partitioning would be as shown below. Note that the order of the partitions I have adopted below is not obligatory; you can change the order if you wish. I prefer to specify precise sizes for the swap and root partitions, and put /home on the last partition so it can occupy the remainder of the disk, whatever size that may be.

UEFI-GPT

Option 1

This is my preferred option because I can edit /etc/fstab and specify that /boot must not be mounted at boot, thus reducing the possibility of the files in /boot getting corrupted.

UEFI-GPT Option 1
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 512 MiB
File system: FAT32
Flags: boot & esp
Code: EF00
Label: ESP
Mount point: /boot/efi
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda3
Size: 512 MiB
File system: ext2
Flags: None
Code: 8300
Label: BOOT
Mount point: /boot Therefore /boot/grub/ will be on this partition if you use GRUB.
/dev/sda4
Size: e.g. 64 GiB (128 GiB if the drive is big)
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root)
/dev/sda5
Size: 1.00 MiB less than the remaining disk space
File system: ext4
Flags: None
Code: 8300
Label: HOME
Mount point: /home
1.00 MiB of empty space at the end of the disk.

* You will often see recommendations to make the size of the swap partition the same as the size of the RAM if you want to be able to put the computer into hibernation. In fact, the Linux kernel is normally configured to compress the contents of the RAM image for hibernation, and I personally have seen the disk image of 4GB of RAM compressed to 23% of that size. Nevertheless, if you have a large HDD you may as well just take the easy route and allocate the size of the swap partition to be the same as the RAM size, even if all of the swap partition will never be used in practice. That way you are guaranteed to be able to put the computer into hibernation.

Below is an example of the above partitioning scheme on a virtual UEFI machine with a 64GiB virtual GPT-partitioned HDD:

root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00
   2         1050624         5244927   2.0 GiB     8200
   3         5244928         6293503   512.0 MiB   8300
   4         6293504        72353791   31.5 GiB    8300
   5        72353792       134215679   29.5 GiB    8300

root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0

Device        Start       End  Sectors  Size Type
/dev/sda1      2048   1050623  1048576  512M EFI System
/dev/sda2   1050624   5244927  4194304    2G Linux swap
/dev/sda3   5244928   6293503  1048576  512M Linux filesystem
/dev/sda4   6293504  72353791 66060288 31.5G Linux filesystem
/dev/sda5  72353792 134215679 61861888 29.5G Linux filesystem

root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system     Name  Flags
 1      1049kB  538MB   537MB   fat32                 boot, esp
 2      538MB   2685MB  2147MB  linux-swap(v1)
 3      2685MB  3222MB  537MB   ext2
 4      3222MB  37.0GB  33.8GB  ext4
 5      37.0GB  68.7GB  31.7GB  ext4

root # blkid
/dev/sda4: LABEL="ROOT" UUID="174ac3e8-f105-4606-bed1-7a1aa22c3631" TYPE="ext4" PARTUUID="01d9c139-fe70-415a-abc6-2351fad33384"
/dev/sda1: UUID="B4C1-7EA5" TYPE="vfat" PARTUUID="d941f728-c386-4f4c-b0c3-aa76f4290774"
/dev/sda2: LABEL="SWAP" UUID="e3ddf9b5-2ae3-4469-a121-0a1a78aa6702" TYPE="swap" PARTUUID="a4daec88-da44-4ae3-8119-01cc81325f03"
/dev/sda3: LABEL="BOOT" UUID="1e24ea9d-5358-4e9b-8667-d7a42e7b6ad7" TYPE="ext2" PARTUUID="b5369ce3-4b44-4d19-be6f-1d226dc71cb3"
/dev/sda5: LABEL="HOME" UUID="87f6a0af-dbed-4587-b810-efca8f269618" TYPE="ext4" PARTUUID="19fd7d00-2d89-4653-af03-e81618a3b70d"

Option 2

You could use this scheme if you are not interested in having /boot on its own partition.

UEFI-GPT Option 2
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 512 MiB
File system: FAT32
Flags: boot & esp
Code: EF00
Label: ESP
Mount point: /boot/efi
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda3
Size: e.g. 64 GiB (128 GiB if the drive is big)
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root) Therefore /boot (and /boot/grub/) will on this partition too.
/dev/sda4
Size: 1.00 MiB less than the remaining space on the disk
File system: ext4
Flags: None
Code: 8300
Label: HOME
Mount point: /home
1.00 MiB of empty space at the end of the disk.

* See my earlier note regarding hibernation.

Below is an example of the above scheme on a virtual UEFI machine with a 64GiB virtual GPT-partitioned HDD:

root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00
   2         1050624         5244927   2.0 GiB     8200
   3         5244928        72353791   32.0 GiB    8300
   4        72353792       134215679   29.5 GiB    8300

root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 54B3C38F-1C55-4A19-9BAA-499C4D0D8DD0

Device        Start       End  Sectors  Size Type
/dev/sda1      2048   1050623  1048576  512M EFI System
/dev/sda2   1050624   5244927  4194304    2G Linux swap
/dev/sda3   5244928  72353791 67108864   32G Linux filesystem
/dev/sda4  72353792 134215679 61861888 29.5G Linux filesystem

root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system     Name  Flags
 1      1049kB  538MB   537MB   fat32                 boot, esp
 2      538MB   2685MB  2147MB  linux-swap(v1)
 3      2685MB  37.0GB  34.4GB  ext4
 4      37.0GB  68.7GB  31.7GB  ext4


root # blkid
/dev/sda3: LABEL="ROOT" UUID="fdf2b11a-8c6b-4bb3-9534-477c3ed49d95" TYPE="ext4" PARTUUID="f393129f-ab32-40fb-bf78-3aead3dd4af0"
/dev/sda1: UUID="C024-8A30" TYPE="vfat" PARTUUID="d941f728-c386-4f4c-b0c3-aa76f4290774"
/dev/sda2: LABEL="SWAP" UUID="1f752a05-a1fb-4c5f-ab2e-079715207b4d" TYPE="swap" PARTUUID="a4daec88-da44-4ae3-8119-01cc81325f03"
/dev/sda4: LABEL="HOME" UUID="041e4ab2-d54c-4092-b445-779997ac09ce" TYPE="ext4" PARTUUID="7e1b8dc0-2f38-4260-95af-fbb80bb72156"

Option 3

You could use this scheme if you are not interested in having /boot and /home on their own partitions.

UEFI-GPT Option 3
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 512 MiB
File system: FAT32
Flags: boot & esp
Code: EF00
Label: ESP
Mount point: /boot/efi
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda3
Size: 1.00 MiB less than the remaining space on the disk
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root) Therefore /boot (and /boot/grub/) and /home will on this partition too.
1.00 MiB of empty space at the end of the disk.

* See my earlier note regarding hibernation.

BIOS-GPT

If you have partitioned a large drive correctly then a computer with BIOS firmware will be able to access partitions larger than 2TiB. One of my computers has BIOS firmware only but can access its 3TiB GPT-partitioned HDDs.

Option 1

This is my preferred option because I can edit /etc/fstab and specify that /boot must not be mounted at boot, thus reducing the possibility of the files in /boot getting corrupted.

BIOS-GPT Option 1
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1 This is the BIOS boot partition
Size: 1.00 MiB
File system: Unformatted
Flags: bios_grub
Code: EF02
Label: Not applicable
Mount point: Not applicable
/dev/sda2
Size: 512 MiB
File system: ext2
Flags: None
Code: 8300
Label: BOOT
Mount point: /boot
/dev/sda3
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda4
Size: e.g. 64 GiB (128 GiB if the drive is big)
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root) Therefore /boot and (/boot/grub/) will on this partition too.
/dev/sda5
Size: 1.00 MiB less than the remaining space on the disk
File system: ext4
Flags: None
Code: 8300
Label: HOME
Mount point: /home
1.00 MiB of empty space at the end of the disk.

* See my earlier note regarding hibernation.

Option 2

You could use this scheme if you are not interested in having /boot on its own partition.

BIOS-GPT Option 2
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1 This is the BIOS boot partition
Size: 1.00 MiB
File system: Unformatted
Flags: bios_grub
Code: EF02
Label: Not applicable
Mount point: Not applicable
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda3
Size: e.g. 64 GiB (128 GiB if the drive is big)
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root) Therefore /boot (and /boot/grub/) will on this partition too.
/dev/sda4
Size: 1.00 MiB less than the remaining space on the disk
File system: ext4
Flags: None
Code: 8300
Label: HOME
Mount point: /home
1.00 MiB of empty space at the end of the disk.

* See my earlier note regarding hibernation.

Option 3

You could use this scheme if you are not interested in having /boot and /home on their own partitions.

BIOS-GPT Option 3
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1 This is the BIOS boot partition
Size: 1.00 MiB
File system: Unformatted
Flags: bios_grub
Code: EF02
Label: Not applicable
Mount point: Not applicable
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
File system: linux-swap
Flags: None
Code: 8200
Label: SWAP
Mount point: None
/dev/sda3
Size: 1.00 MiB less than the remaining space on the disk
File system: ext4
Flags: None
Code: 8300
Label: ROOT
Mount point: / (root) Therefore /boot and /home will on this partition too.
1.00 MiB of empty space at the end of the disk.

* See my earlier note regarding hibernation.

BIOS-MBR

Option 1

This is my preferred option because I can edit /etc/fstab and specify that /boot must not be mounted at boot, thus reducing the possibility of the files in /boot getting corrupted.

BIOS-MBR Option 1
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 512 MiB
Type: Primary
File system: ext2
Flags: boot
Label: BOOT
Mount point: /boot
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
Type: Primary
File system: linux-swap
Flags: None
Label: SWAP
Mount point: None
/dev/sda3
Size: e.g. 64 GiB (128 GiB if the drive is big)
File system: ext4
Flags: None
Label: ROOT
Mount point: / (root)
/dev/sda4
Size: remaining space on the disk
Type: Primary
File system: ext4
Flags: None
Label: HOME
Mount point: /home

* See my earlier note regarding hibernation.

Option 2

You could use this scheme if you are not interested in having /boot on its own partition.

BIOS-MBR Option 2
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 16 GiB for a computer with 16 GiB of RAM*
Type: Primary
File system: linux-swap
Flags: None
Label: SWAP
Mount point: None
/dev/sda2
Size: e.g. 64 GiB (128 GiB if the drive is big)
Type: Primary
File system: ext4
Flags: boot
Label: ROOT
Mount point: / (root) Therefore /boot will be on this partition too.
/dev/sda3
Size: remaining space on the disk
Type: Primary
File system: ext4
Flags: None
Label: HOME
Mount point: /home

* See my earlier note regarding hibernation.

Option 3

You could use this scheme if you are not interested in having /boot and /home on their own partitions.

BIOS-MBR Option 3
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 16 GiB for a computer with 16 GiB of RAM*
Type: Primary
File system: linux-swap
Flags: None
Label: SWAP
Mount point: None
/dev/sda2
Size: remaining space on the disk
Type: Primary
File system: ext4
Flags: boot
Label: ROOT
Mount point: / (root) Therefore /boot and /home will be on this partition too.

* See my earlier note regarding hibernation.

Option 4

If you want to have more than four partitions — let’s say you wanted to have a separate NTFS partition, for example — you would need to use an Extended Partition.

BIOS-MBR Option 4
1.00 MiB of empty space at the beginning of the disk.
/dev/sda1
Size: 512 MiB
Type: Primary
File system: ext2
Flags: boot
Label: BOOT
Mount point: /boot
/dev/sda2
Size: 16 GiB for a computer with 16 GiB of RAM*
Type: Primary
File system: linux-swap
Flags: None
Label: SWAP
Mount point: None
/dev/sda3
Size: Remainder of disk
Type: Extended
File system: Not applicable
Flags: None
Label: Not applicable
Mount point: Not applicable
/dev/sda4
Will not exist
/dev/sda5
Size: e.g. 128GiB
Type: Logical
File system: ext4
Flags: None
Label: ROOT
Mount point: / (root)
/dev/sda6
Size: e.g. 256GiB
Type: Logical
File system: ext4
Flags: None
Label: HOME
Mount point: /home
/dev/sda7
Size: remaining space on the disk
Type: Logical
File system: NTFS
Flags: None
Label: NTFS
Mount point: /media/NTFS

* See my earlier note regarding hibernation.

Below is an example of the above scheme (this happens to be the scheme on my main laptop):

root # fdisk -l /dev/sda
Disk /dev/sda: 698.7 GiB, 750156374016 bytes, 1465149168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x291ba0e7

Device     Boot     Start        End    Sectors   Size Id Type
/dev/sda1            2048     264191     262144   128M 83 Linux
/dev/sda2          264192   33822719   33558528    16G 82 Linux swap / Solaris
/dev/sda3        33822720 1465147391 1431324672 682.5G  5 Extended
/dev/sda5        33824768  302260223  268435456   128G 83 Linux
/dev/sda6       302262272  839133183  536870912   256G 83 Linux
/dev/sda7       839135232 1465147391  626012160 298.5G  7 HPFS/NTFS/exFAT

root # lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,LABEL,PARTFLAGS /dev/sda
NAME   TYPE   SIZE FSTYPE  MOUNTPOINT  LABEL PARTFLAGS
sda    disk 698.7G                           
├─sda1 part   128M ext2    /boot       BOOT  
├─sda2 part    16G swap    [SWAP]      SWAP  
├─sda5 part   128G ext4    /           ROOT  
├─sda6 part   256G ext4    /home       HOME  
└─sda7 part 298.5G ntfs-3g /media/NTFS NTFS

Notice that the boot flag is not set. Nevertheless the laptop boots fine.

Command-line tools

Below are examples of command-line utilities parted, gdisk and fdisk examining a GPT-partitioned HDD and an MBR-partitioned HDD. The original fdisk utility predates the invention of GPT, but the latest versions of fdisk understand the GPT design (you can check this by using the command ‘man fdisk‘). Personally, to partition GPT HDDs from the command line I would use parted or gdisk before fdisk, and to partition MBR HDDs from the command line I would use parted or fdisk before gdisk. Mind you, I like an easy life and so I tend to use the GUI tools GParted or KDE Partition Manager to partition and format an HDD for Linux.

GPT-partitioned HDD

root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system     Name       Flags
 1      2097kB  539MB   537MB   fat32                      boot, esp
 2      539MB   1076MB  537MB   ext2            /boot
 3      1076MB  3223MB  2147MB  linux-swap(v1)  linuxswap
 4      3223MB  37.6GB  34.4GB  ext4            /
 5      37.6GB  68.7GB  31.1GB  ext4            /home

root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 9807AF0F-8BD5-4727-A3CD-9995B2705732
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 134217694
Partitions will be aligned on 2048-sector boundaries
Total free space is 8125 sectors (4.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            4096         1052671   512.0 MiB   EF00  
   2         1052672         2101247   512.0 MiB   8300  /boot                                                                    
   3         2101248         6295551   2.0 GiB     8200  linuxswap                                                                
   4         6295552        73404415   32.0 GiB    8300  /                                                                        
   5        73404416       134213631   29.0 GiB    8300  /home                                                                    
root # fdisk -l /dev/sda                                                                                           
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors                                                                       
Units: sectors of 1 * 512 = 512 bytes                                                                                             
Sector size (logical/physical): 512 bytes / 512 bytes                                                                             
I/O size (minimum/optimal): 512 bytes / 512 bytes                                                                                 
Disklabel type: gpt                                                                                                               
Disk identifier: 9807AF0F-8BD5-4727-A3CD-9995B2705732                                                                             
                                                                                                                                  
Device        Start       End  Sectors  Size Type                                                                                 
/dev/sda1      4096   1052671  1048576  512M EFI System
/dev/sda2   1052672   2101247  1048576  512M Linux filesystem
/dev/sda3   2101248   6295551  4194304    2G Linux swap
/dev/sda4   6295552  73404415 67108864   32G Linux filesystem
/dev/sda5  73404416 134213631 60809216   29G Linux filesystem

MBR-partitioned HDD

root # parted /dev/sda print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type     File system     Flags
 1      1049kB  538MB   537MB   primary  ext2            boot
 2      538MB   2685MB  2147MB  primary  linux-swap(v1)
 3      2685MB  37.0GB  34.4GB  primary  ext4
 4      37.0GB  68.7GB  31.7GB  primary  ext4

root # gdisk -l /dev/sda
GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. 
***************************************************************


Warning! Secondary partition table overlaps the last partition by
33 blocks!
You will need to delete this partition or resize it in another utility.
Disk /dev/sda: 134217728 sectors, 64.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): F6E9E53E-33BE-44CB-BEFC-D93E03B79B84                                                   
Partition table holds up to 128 entries                                                                        
First usable sector is 34, last usable sector is 134217694                                                     
Partitions will be aligned on 2048-sector boundaries                                                           
Total free space is 2014 sectors (1007.0 KiB)                                                                  

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   8300  Linux filesystem
   2         1050624         5244927   2.0 GiB     8200  Linux swap
   3         5244928        72353791   32.0 GiB    8300  Linux filesystem
   4        72353792       134217727   29.5 GiB    8300  Linux filesystem
root # fdisk -l /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7b9f1623

Device     Boot    Start       End  Sectors  Size Id Type
/dev/sda1  *        2048   1050623  1048576  512M 83 Linux
/dev/sda2        1050624   5244927  4194304    2G 82 Linux swap / Solaris
/dev/sda3        5244928  72353791 67108864   32G 83 Linux
/dev/sda4       72353792 134217727 61863936 29.5G 83 Linux

Notice the gdisk warning that the last partition would not be viable on a GPT-partitioned HDD because there would not be space for the Secondary GPT. However, as this is an MBR-partitioned HDD for use with a BIOS firmware computer, that does not apply.

A warning note if installing Ubuntu on a UEFI computer

When I installed Ubuntu Desktop 16.04.1 in a virtual machine I encountered a bug (in VirtualBox? in the Ubuntu Installer?) which results in subsequent reboots leaving the virtual machine running the UEFI Shell instead of launching GRUB and booting Ubuntu. To fix that, I did the following as soon as Ubuntu booted from the virtual HDD for the first time after I had clicked ‘Restart Now’ in the ‘Installation Complete’ window:

user $ sudo su
root # mount /dev/sda1 /mnt
root # cd /mnt
root # echo "\EFI\ubuntu\grubx64.efi" > startup.nsh
root # cd
root # umount /dev/sda1
root # exit

The partition /dev/sda1 being the FAT32 ESP in this case.

This creates the file /boot/efi/startup.nsh required by the UEFI Shell. Then you can reboot and all should work as intended, i.e. the UEFI machine boots to the UEFI Shell which, after a few seconds, launches GRUB.

UPDATE (16 February 2017): A downside to the above approach is the 5-second timeout in the UEFI Shell until startup.nsh is launched. Below is an alternative that avoids having to wait for the 5-second countdown in the UEFI Shell until startup.nsh is launched. The downside is that you must remember to repeat this procedure if a new version of GRUB is installed and there is a new version of /EFI/ubuntu/grubx64.efi.

user $ sudo su
root # mount /dev/sda1 /mnt
root # cd /mnt/EFI/
root # ls
ubuntu
root # ls ubuntu
fw  fwupx64.efi  grub.cfg  grubx64.efi  MokManager.efi  shimx64.efi
root # mkdir BOOT
root # cp ubuntu/grubx64.efi BOOT/BOOTX64.EFI
root # cd
root # umount /dev/sda1
root # exit

See the Arch Linux Wiki article VirtualBox – 2.1 Installation in EFI mode.

A warning note if installing Gentoo on a UEFI computer

To date, the Gentoo Minimal Installation CD does not support UEFI, and therefore I recommend that you use SystemRescueCd instead. It is a Gentoo-based LiveCD with several tools useful for installing Gentoo, including a Web browser so you can access the on-line Gentoo documentation during installation. You can follow the Gentoo Installation Guide verbatim. SystemRescueCd also has a Desktop Environment with various GUI utilities, so you could partition the HDD using GParted instead of the command-line utilities if you wish. SystemRescueCd also comes with various wireless network card drivers and a network manager, so there is a good chance you will be able to connect easily to a wireless network if you prefer (I once used SystemRescueCd to install Gentoo on a laptop using Wi-Fi alone, as a wired connection was not convenient at the time).

How can I find out in Linux if a computer has booted using UEFI?

Check if the RAM-based directory /sys/firmware/efi/ exists. If it does not exist, the computer did not boot using UEFI.

Further Reading

  1. Wikipedia – BIOS
  2. Wikipedia – Master boot record
  3. UEFI Specification Version 2.6, January 2016
  4. Wikipedia – Unified Extensible Firmware Interface
  5. Wikipedia – GUID Partition Table
    Also, the diagram GUID Partition Table Scheme in that article is quite helpful in understanding the layout of a GPT-partitioned HDD.
  6. Wikipedia – BIOS boot partition
    Also, the diagram GNU GRUB 2 in that article is quite helpful in understanding: a) MBR partitioning; b) how GRUB 2 fits on an MBR-partitioned HDD; c) GPT partitioning; d) how GRUB 2 fits on a GPT-partitioned HDD; e) where the BIOS boot partition fits on a GPT-partitioned HDD and how it is used by GRUB 2.
  7. GNU GRUB Manual – 3.4 BIOS installation
  8. Ubuntu Documentation – UEFI
  9. Gentoo Installation Guide – Preparing the disks
  10. Ubuntu Bug Reports – Bug No. 811485 – Ubuntu partman-efi package – EFI SYSTEM PARTITION should be atleast 100 MiB size and formatted as FAT32, not FAT16
  11. Roderick W. Smith’s Web Page