EDIT: When I wrote this answer very few distributions shipped with an EFI_STUB configured kernel so one had to build a custom one. Nowadays most distributions ship a suitably configured kernel and a custom build is not required any longer. In this case the sections “Set up your partitions” and “Setting things up” are the interesting ones, “Requirements” and “Compiling the kernel” can be skipped.
I don't know how Windows handles UEFI, but from the Debian side it's pretty
straightforward.
Set up your partitions
Use the GPT partition scheme, not MBR.
To boot from a GPT partition with UEFI a dedicated boot partition is mandated,
called the EFI SYSTEM PARTITION (ESP). It is not mandatory, but the most
compatible way is to use a FAT32 partition. A size of 200 MiB should be fine
for most cases.
To register the partition as a ESP, it has to be flagged with the boot
flag.
In contrast to MBR schemes, the boot flag is only used to indicate the ESP,
not the partitions to be able to boot from.
UEFI uses a directory structure \EFI\<vendor>\<application>.efi
to store
UEFI applications. A directory separator is denoted by a backslash, even on
Linux. could be a distribution name, the actual value is not relevant
to the UEFI.
Applications can be system utilities like memory checkers or an UEFI shell. It
can also be an OS loader or the operating system itself. These applications
need to be registered in the UEFI to be able to be launched at boot time.
Requirements
The Linux kernel version >=3.3 can be loaded directly by the UEFI. The kernel can act as its own loader. This is called EFISTUB. The following kernel configurations are needed.
CONFIG_EFI=y
CONFIG_EFI_PARTITION=y
CONFIG_EFI_STUB=y
CONFIG_RELOCATABLE=y
CONFIG_FB_EFI=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_EFI_VARS=m
A kernel with this configuration is currently not in Debian stable, yet. You can either
bake your own kernel or use the one from the experimental tree in that case you can skip the next paragraph.
Compiling the kernel
(probably not necessary any more, see edit)
If you decide to compile the kernel here are short instructions how to do that. If you run into problems, there is plenty of information available on how to compile a kernel.
Getting the source
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Check out one particular version
git checkout v3.6
Configuring kernel
make menuconfig
Make the settings that are needed on your system or leave it as it
is if you have nothing to customize. This writes the kernel
configuration to the file .config
.
Make sure the settings from the previous paragraph are set. It also
makes sense to select CONFIG_INPUT_EVBUG=n
. Otherwise your logs
will be filled with GiB of junk.
Building kernel
INSTALL_MOD_STRIP=1 make-kpkg --uc --us binary-arch
The packages are created in the parent directory.
Installing kernel
dpkg -i linux-image-3.5.0_Custom.deb linux-headers-3.5.0_Custom.deb
Building initramfs
mkinitramfs -o /boot/initrd.img-3.6.0-amd64 3.6.0
3.6.0 is the kernel version. It defaults to the running kernel,
which is not a good choice, since you are still running the old
kernel.
Setting things up
To be able to boot the Linux kernel, it has to be copied to the ESP together
with the initramfs. Given that the ESP is mounted at /boot/efi
/boot/efi/EFI/debian/vmlinuz-3.6.0.efi
/boot/efi/EFI/debian/initrd.img-3.6.0
NOTE: To ensure compatibility with most systems the extenstion efi
has to
be added to the kernel.
Now the kernel can be registered in the UEFI. We use the tool efibootmgr
for
that.
echo "root=UUID=3a4287b6-b3a7-4721-da38-acc38a928278 ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\debian\\initrd.img-3.6.0" |
iconv -f ascii -t ucs2 |
efibootmgr \
--create \
--gpt \
--disk /dev/sda \
--part 4 \
--label "Debian Linux kernel 3.6.0" \
--loader "\\EFI\\debian\\vmlinuz-3.6.0" \
--write-signature \
--append-binary-args -
The argument of --disk
is the device where the kernel resides, not the ESP.
--part
is the partition number where the kernel resides. --label
is the
entry in the UEFI boot menu.
To see a list of the available entries, just launch efibootmgr
without
arguments. Syntax to delete a particular entry
efibootmgr -b entry (hex) -B
for example:
efibootmgr -b 001a -B
These instructions don't handle the case of a kernel update. The kernel and initramfs are not automatically copied to the ESP. This can be done using a short script which copies the kernel and initramfs to the ESP and runs efibootmgr
. This script can be placed in /etc/kernel/postinst.d
to be launched automatically after the kernel has been updated.
Note: A boot manager like GRUB is not needed, UEFI itself acts as a boot manager.
That's all you need from the Linux side, I don't know what it takes to add
Windows.