Feature #5835

nx bit

Added by Tails 2013-07-18 07:46:58 . Updated 2014-03-05 21:31:59 .

Status:
Resolved
Priority:
Normal
Assignee:
Category:
Target version:
Start date:
Due date:
% Done:

0%

Feature Branch:
Type of work:
Code
Blueprint:

Starter:
0
Affected tool:
Deliverable for:

Description

{{toc}}

Rationale and context

The NX bit helps enabling executable space protection. Most 64bits, and some 32bits, x86 CPUs support this.

On Linux, PAE must be enabled to get the NX bit enabled. We cannot blindly enable PAE, as it "causes pre-Pentium Pro (including Pentium MMX) and Celeron M and Pentium M processors without NX support to fail to boot" (Wikipedia.

So we cannot default to use PAE, and should at least provide the non-bigmem one as an alternative choice in the bootloader or wait for non-PAE systems to be rare enough so that we can stop supporting them.

As of 2.6.39, Debian –686 kernels have PAE enabled (reference: Ben’s blog, that’s why we now ship a –486 kernel.

If we don’t want to ship –486 until non-PAE systems die, and forget about NX bit until then, we have to ship both –686-pae and –486, and have the bootloader autodetect the most appropriate one depending on what the kernel supports.

Implementation

Done

The feature/multikernel branch (merged into experimental):

  • installs two kernels (-486, -686-pae)
  • patches the syslinux menu configuration to autoselect best kernel wrt. hardware support, and automatically jump to an arch-specific appropriate sub-menu
  • tested on CPUs: 486, amd64, 686 without PAE
  • successfully run the Tails USB Installer with a -686-pae kernel
  • given up shipping an amd64 kernel, due to the VirtualBox bugs about guest additions vs. 32-bit userspace + 64-bit kernel :(
  • memtest with 686-pae on 4GB RAM and more was tried: worse results than with sdmem (2.5GB of the known pattern found after "wiping" with memtest, vs. 1.5GB when using sdmem), so we’re back to sdmem (54c81c1 reverted)

Next steps

done in Tails 0.14

Possibly later

Resources

ifcpu64

The ifcpu64.c32 module seems to provide what we need, allowing to do different things for 64-bit hardware, 32-bit hardware with PAE support and 32-bit hardware without PAE, like this:

label boot_kernel
    com32 ifcpu64.c32
    append boot_kernel_64 -- boot_kernel_32pae -- boot_kernel_32
label boot_kernel_32
    kernel vmlinuz_32
    append ...
label boot_kernel_32pae
    kernel vmlinuz_32pae
    append ...
label boot_kernel_64
    kernel vmlinuz_64
    append ...

Unfortunately, it does not select a default kernel, but boots it right away. So instead of booting a Linux kernel, we can boot the vesamenu.c32 module with a different configuration file for each kernel:

label select_menu
    com32 /syslinux/ifcpu64.c32
    append menu_amd64 -- menu_686-pae -- menu_486
label menu_amd64
    kernel /syslinux/vesamenu.c32
    append live_amd64.cfg
label menu_686-pae
    kernel /syslinux/vesamenu.c32
    append live_686-pae.cfg
label menu_486
    kernel /syslinux/vesamenu.c32
    append live_486.cfg
default select_menu

Discarded

HDT

The HDT (hardware detection tool) syslinux module (homepage, page on syslinux wiki has code that might help supporting this; it’s been shipped in mainline syslinux for a while. On the other hand does not offer any kind of feature that can be used to parameterized the boot menu.

default64 menu keyword

Debian multi-arch installer’s syslinux menu autodetects amd64-compatible hardware and pre-selects the right default kernel. Seems like it uses the default64 menu keyword (see debian-installer Git repository). Unfortunately, this solution is not suitable for us because it does not allow to select a kernel depending on PAE support, and is not part of recent syslinux package.

ifcpu.c32

Other COM32 modules shipped with syslinux might be better suited for our specific needs. See especially ifcpu.c32; according to its source code, it can "run one command if system match some CPU features, another if it doesn’t" and is supposed to be used e.g. like this:

label ifcpu
    com32 ifcpu.c32
    append pae -- boot_entry_1 -- boot_entry_2

label boot_entry_1
    kernel vmlinuz_entry1
    append ...

label boot_entry_2
    kernel vmlinuz_entry2
    append ...

… which would almost suit our needs but only allows two alternatives, while we need three.


Subtasks


History

#1 Updated by intrigeri 2013-07-19 01:44:19

  • Type of work set to Code

Type of work: Code

#2 Updated by BitingBird 2014-03-05 21:31:59

  • Description updated
  • Target version deleted (Hole in the Roof)
  • Starter set to No