Ben's technical blog

Sat, 14 Jan 2012

Installing Debian GNU/Linux and Windows dual-boot under UEFI

I thought it was about time to get a faster machine for... well, mostly for compiling kernels faster, but I'm sure I will find other applications for it. I was originally intending to upgrade my laptop (Thinkpad T61, 1.8 GHz Core 2 Duo) but it seems that in the 3 years since I bought it second-hand laptop prices have not dropped in line with Moore's law. So instead I decided to upgrade (well, replace most of) a desktop PC.

The last time I got a new desktop at home was in 2002. It has an Athlon XP, PATA drives and a huge CRT monitor. It has had some upgrades since then (DVD writer, more RAM, slightly faster CPU, replacement fan and PSU). Obviously it was time to replace motherboard, CPU and RAM. Not so obviously, the PSU needed changing again as modern CPUs apparently need more 12V electrons (?!). The DVD writer was salvageable via a USB adapter and its local HD is currently a laptop drive (the only spare SATA HD I had). The monitor is of course reusable, though the firmware setup program doesn't entirely agree with it.

Windows

Yes, I do sometimes run Windows. It's for games, and also seems to be needed for streaming video with stupid DRM.

On the assumption that Windows is less likely to play nice with an existing installation, I tried installing it first. The firmware appear to allow me to boot the DVD in either BIOS or UEFI mode, so I selected the UEFI option. This worked so far as loading the initramfs (or whatever the Windows equivalent is) but then Windows was lacking a driver to access the DVD. This stumped me for a day or so until I realised I had plugged the drive into a USB 3 (XHCI) port. Apparently Windows 7 SP1 still doesn't include an XHCI driver in the installer (but neither does Debian 6.0.3 - we should fix that).

The installation was mostly uneventful after this. The Windows installer includes a reasonably capable partition editor.

Debian

Installation of files was entirely uneventful. The installer correctly detected the GPT (GUID partition table) created by Windows. However, it was not able to install a boot loader. Currently it only includes support for the LILO and GRUB-PC boot loaders that run under BIOS.

After much experimentation and cursing, I found instructions for installing Debian Squeeze on XServe 3.1 by Jan Peter Alexander Rajagukguk, which put me on the right track. It seems that the grub-install script for GRUB-EFI in squeeze (and maybe other parts of the package) doesn't actually work. However. JP's direction to build GRUB from source is no longer necessary. Here's what I did (minus the mis-steps):

  1. Boot the installer in rescue mode and open a shell on the installed system:
    # # We start in dash, so switch to bash.
    # exec bash
    # mkdir -p /boot/efi
    # # Mount the EFI boot partition by UUID.
    # # It's probably called sda1 now, but is subject to change.
    # ls -l /dev/disk/by-uuid
    ...
    # echo >>/etc/fstab 'UUID=efi-boot-uuid /boot/efi vfat defaults 0 0'
    # mount /boot/efi
    # # Enable unstable sources, but use stable by default
    # echo >>/etc/apt/apt.conf 'APT::Default-Release "squeeze";'
    # echo >>/etc/apt/sources.list 'deb http://cdn.debian.net/debian/ sid main'
    # apt-get update
    ...
    # # Install unstable grub-efi-amd64
    # apt-get install -t unstable grub-efi-amd64
    ...
    # # Install GRUB to the EFI partition.  The '--removable' options
    # # inhibits setting EFI variables, which won't work because we booted
    # # through BIOS emulation.  Instead, it installs as the default boot
    # # loader.
    # grub-install --bootloader-id=GRUB --removable
    # # On the AMI/ASUS firmware, you cannot select a new bootloader
    # # directly but can invoke a 'shell'.  So I made GRUB the shell:
    # cp /boot/efi/boot/grub/grub.efi /boot/efi/shellx64.efi
    # exit
    
  2. Reboot and select GRUB as the boot loader if necessary. In my case I had to enter the setup program and select 'EFI shell'. Debian should now boot from the hard drive.
  3. Add a non-volatile boot option for GRUB (and make it the default):
    # apt-get install efibootmgr
    ...
    # modprobe efivars
    # efibootmgr -c -l '\efi\grub\grubx64.efi' -L GRUB
    

posted at: 20:25 | path: / | permanent link to this entry