nx_bit.mdwn 4.73 KB
Newer Older
Tails developers's avatar
Tails developers committed
1
2
[[!toc levels=2]]

Tails developers's avatar
Sum up.    
Tails developers committed
3
4
Rationale and context
=====================
5

Tails developers's avatar
Typo    
Tails developers committed
6
The [[!wikipedia NX_bit]] helps enabling executable space protection.
7
8
9
10
11
12
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"
Tails developers's avatar
Sum up.    
Tails developers committed
13
([Wikipedia](https://secure.wikimedia.org/wikipedia/en/wiki/NX_bit#Linux)).
14

Tails developers's avatar
Sum up.    
Tails developers committed
15
16
17
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.
T(A)ILS developers's avatar
T(A)ILS developers committed
18

Tails developers's avatar
Sum up.    
Tails developers committed
19
20
21
As of 2.6.39, Debian -686 kernels have PAE enabled (reference: [Ben's
blog](http://womble.decadent.org.uk/blog/upcoming-changes-in-debian-linux-packages-for-i386.html)),
that's why we now ship a -486 kernel.
T(A)ILS developers's avatar
T(A)ILS developers committed
22

Tails developers's avatar
Sum up.    
Tails developers committed
23
24
25
26
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.
27

Tails developers's avatar
Tails developers committed
28
29
Implementation
==============
30

Tails developers's avatar
Tails developers committed
31
32
### Done

33
34
The `feature/multikernel` branch:

35
36
37
- installs three kernels (`-486`, `-686-pae`, `-amd64`) => makes the
  ISO 66MB bigger (current devel branch that avoids shipping every
  kernel twice)
38
39
40
41
42
- offers two menu entries (*Start Tails* and *Start Tails (failsafe)*)
  that autoselect best kernel wrt. hardware support; other menu
  entries auto-generated by live-build are hidden, but behind the
  curtain the autodetection code jumps to the one it thinks is best

Tails developers's avatar
Tails developers committed
43
### Next steps
44

Tails developers's avatar
TODO++    
Tails developers committed
45
46
47
48
- stuff added to the command-line in the syslinux menu is ignored;
  seems like the ifcpu64 module does not pass parameters to the other
  (hidden, auto-detected) menu entry it runs; inserting `--` between
  `append live-amd64 -- live-686-pae -- live` and the additional
Tails developers's avatar
Tails developers committed
49
50
51
52
53
54
55
56
  parameters was tried, and failed too; so,
  * on the short run, we can forget the ifcpu64 part, and ship
    a multikernel image with a "one line per kernel" (486, 686-pae,
    amd64) menu - will be better than nothing; [[!tag todo/code]]
  * on the long run, we probably have to e.g.
    add another level of redirection, and -if possible- have ifcpu64
    "boot" a submenu that displays the autodetected kernel, and provides
    ways to edit it. [[!tag todo/code]]
57
58
- check that our build system does not do stuff say, for *the one and
  only* kernel
59
60
61
- [[!taglink todo/wait]] for a graphical [[todo/boot_menu]] to take
  over the language choosing functionality.

Tails developers's avatar
Tails developers committed
62
63
Resources
=========
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
The `ifcpu64.c32`
[module](http://syslinux.zytor.com/wiki/index.php/Ifcpu64.c32) 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; we want to allow the user to customize the kernel command
line, so we have to add a (selected by default) menu entry that reads
something like *Autodetect and boot*.

Tails developers's avatar
Tails developers committed
89
## Discarded
90

Tails developers's avatar
Tails developers committed
91
### HDT
92
93
94
95
96
97
98
99

The HDT (hardware detection tool) syslinux module
([homepage](http://www.hdt-project.org/), [page on syslinux
wiki](http://syslinux.zytor.com/wiki/index.php/Hdt_(Hardware_Detection_Tool)))
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.

Tails developers's avatar
Tails developers committed
100
### default64 menu keyword
101

102
103
104
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
105
106
107
108
109
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](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=505496#16).

Tails developers's avatar
Tails developers committed
110
### ifcpu.c32
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

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 ...

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