bootpc.ms 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. .HTML "Bootstrapping Plan 9 on PCs
  2. .de Os\" overstrike argument
  3. \\$1\l'|0–'
  4. ..
  5. .
  6. .TL
  7. Bootstrapping Plan 9 on PCs
  8. .AU
  9. Geoff Collyer
  10. .br
  11. .CW geoff@plan9.bell-labs.com
  12. .AI
  13. .MH
  14. .AB
  15. What's interesting or tricky about bootstrapping Plan 9 on PCs?
  16. .AE
  17. .
  18. .SH
  19. Introduction
  20. .LP
  21. Plan 9 has new PC bootstraps,
  22. .I 9boot
  23. and
  24. .I 9load,
  25. replacing the decade-old
  26. .I 9pxeload
  27. and
  28. .I 9load
  29. programs.
  30. What did we learn while writing them?
  31. .SH
  32. PC Constraints
  33. .LP
  34. The IBM PC imposes quite a few constraints on bootstrap programs
  35. (programs that load operating system kernels).
  36. A PC starts executing in 16-bit `real' (Intel 8086) mode
  37. and has no boot monitor, as other machines do,
  38. just a primitive BIOS that will perform a power-on self-test (POST)
  39. and attempt to read boot sectors
  40. from disks or load a modest payload from the network via TFTP.
  41. (Actually some new machines have slightly less primitive
  42. boot loaders called (U)EFI, but we don't deal with EFI.)
  43. The boot sectors must load further bootstrap programs
  44. that resemble the TFTP payload.
  45. These bootstrap programs can only address the first megabyte of memory
  46. until they get out of real mode,
  47. and even then the upper 384KB of the initial megabyte is reserved
  48. for device ROMs.
  49. .LP
  50. BIOS calls (via the
  51. .CW INT
  52. instruction)
  53. only work in real mode,
  54. so the bootstraps execute BIOS calls to learn the machine's
  55. memory map and power management configuration,
  56. and stash the results in the first megabyte
  57. for later retrieval by the loaded kernel.
  58. Empirically, some BIOSes enable interrupts (with
  59. .CW STI
  60. instructions)
  61. during BIOS calls,
  62. so the bootstraps disable them again after each call;
  63. failure to do so often results in an interrupt,
  64. perhaps from the clock, resetting the machine.
  65. .CW 9loadusb
  66. returns briefly to real mode
  67. to read USB devices and has mixed results with that.
  68. .LP
  69. Getting into 32-bit protected mode permits addressing the first 4GB of memory,
  70. but first it is necessary to enable the A20 address line (the
  71. .CW 1<<20
  72. bit).
  73. For (extreme) backward compatibility, this bit is normally held to zero
  74. until software requests that it be released, and holding it to zero will cause
  75. references to the second megabyte to be mapped to the first, etc.,
  76. causing bizarre-seeming memory corruption.
  77. The old technique was to ask the keyboard controller to release it,
  78. but some systems now have no keyboard controller (they are servers
  79. or have USB keyboards).
  80. We have found it necessary to keep trying different methods until one succeeds
  81. and is verified to have succeeded.
  82. The new bootstraps also try an
  83. .CW INT
  84. .CW 15
  85. BIOS call and
  86. manipulation of port
  87. .CW 0x92
  88. (`system control' on some systems).
  89. .LP
  90. Even in protected mode with A20 enabled, some systems
  91. force a gap in the physical address space between 15MB and 16MB,
  92. which must be avoided.
  93. .
  94. .SH
  95. Plan 9 Requirements
  96. .IP • 3
  97. The new bootstraps must be able to load 64-bit
  98. .CW amd64
  99. kernels as well as
  100. .CW 386
  101. ones.
  102. In addition to Plan 9 boot image format,
  103. the new bootstraps understand ELF and ELF64 formats.
  104. .IP •
  105. Plan 9 kernels need to be started in 32-bit protected mode and
  106. implicitly assume that A20 is enabled.
  107. .IP •
  108. They expect a parsed
  109. .CW /cfg/pxe/\fIether
  110. or
  111. .CW plan9.ini
  112. file to be present at physical address
  113. .CW 0x1200
  114. and that
  115. .I 9load
  116. will have added entries to it describing
  117. any disk partitions found.
  118. (\c
  119. .I 9boot
  120. does not do this and so kernels loaded by it
  121. that care about disk partitions will need
  122. .CW readparts=
  123. in
  124. .CW plan9.ini .)
  125. .IP •
  126. They expect automatic power management information obtained from the
  127. BIOS to be present in the first megabyte.
  128. .IP •
  129. Our
  130. .CW amd64
  131. kernels (9k, Nix, etc.)
  132. also expect a Gnu
  133. .I multiboot
  134. header containing any arguments and a memory map.
  135. .
  136. .SH
  137. Non-Requirements
  138. .IP • 3
  139. The bootstraps should ignore secondary processors, leaving them in reset.
  140. .IP •
  141. The bootstraps need not do anything with floating point.
  142. .
  143. .SH
  144. Techniques and Tricks
  145. .LP
  146. Our new bootstraps are stripped-down Plan 9 PC kernels
  147. without system calls and user mode processes.
  148. They share the vast majority of their code with the ordinary PC kernels;
  149. about 10,000 lines of C are new or different in the bootstraps.
  150. In particular, they use the ordinary PC kernel's device drivers,
  151. unmodified.
  152. .I 9boot
  153. loads kernels via PXE;
  154. .I 9load
  155. loads kernels from disk.
  156. This is more specialised than the old all-in-one
  157. .I 9load .
  158. .LP
  159. From protected mode,
  160. the bootstraps initially enable paging for their own use.
  161. Before jumping to the loaded kernel, they revert
  162. to 32-bit protected mode, providing a known initial CPU state
  163. for the kernels.
  164. .LP
  165. Self-decompression of the bootstraps
  166. can help to relieve the 512KB/640KB payload limit.
  167. Russ Cox's decompressing header* code is about 9K all told,
  168. .FS
  169. * see
  170. .CW http://plan9.bell-labs.com/wiki/plan9/Replacing_9load
  171. .FE
  172. including BIOS calls to get APM and E820 memory map info.
  173. We only bother with this currently for
  174. .I 9boot .
  175. The bootstraps also will decompress
  176. .I gzip -ped
  177. kernels loaded from disk,
  178. mainly for CD or floppy booting, where they are limits on kernel size.
  179. .LP
  180. Figure 1 shows the memory map in effect while the bootstraps run.
  181. .KF
  182. .TS
  183. center ;
  184. cb s ,
  185. n cw(3i) .
  186. Figure 1: Layout of physical memory during bootstrapping
  187. .sp 0.3v
  188. 0 misc., including bios data area
  189. _
  190. 31K T{
  191. start of pxe decomp + compressed 9boot.
  192. decompresses to 9MB.
  193. T}
  194. _
  195. 64K T{
  196. start of pbs
  197. T}
  198. _
  199. 512K pxe loader from ROM
  200. _
  201. 640K UMB; device ROMs
  202. _
  203. 1M kernel
  204. _
  205. 9M T{
  206. 9boot after decomp.
  207. (decompresses kernel.gz at 13M.)
  208. loads kernel at 1M.
  209. T}
  210. _
  211. 13M (kernel.gz)
  212. _
  213. 15M no-man's land
  214. _
  215. 16M malloc arena for 9boot
  216. \&...
  217. .TE
  218. .KE
  219. .LP
  220. Our USB stack (at least 3 HCI drivers plus user-mode drivers,
  221. implying system calls and user-mode support) is too big
  222. to fit in the first 640KB,
  223. so the bootstraps try to get BIOSes to read from USB devices
  224. and some of them do.
  225. .LP
  226. We strongly prefer PXE booting; disk booting is a poor second.
  227. PXE booting minimises the number of copies of kernels that must
  228. be updated and ensures that machines boot the latest kernels.
  229. Reading via 9P (as user
  230. .I none )
  231. would be even better: just read
  232. .CW /cfg/pxe/$ether
  233. and
  234. .CW /386/9pccpu .
  235. This would probably require adding
  236. .CW devmnt
  237. back into the bootstrap kernels.
  238. .
  239. .br
  240. .ne 6
  241. .SH
  242. Future
  243. .Os Horrors
  244. Directions
  245. .LP
  246. We haven't dealt at all with (U)EFI, `secure boot', GPTs nor GUIDs.
  247. We can use Plan 9 partition tables instead of GPTs to address disks larger
  248. than 2 TB.
  249. .
  250. .SH
  251. Lessons Learned
  252. .LP
  253. A disabled A20 line can masquerade as all sorts of baffling problems.
  254. It is well worth ensuring that it is truly enabled.
  255. .LP
  256. Virtual-machine hypervisors can be good test-beds and provide
  257. better crash diagnostics than the
  258. blank screen you get on real hardware,
  259. but they can also mislead
  260. (e.g.,
  261. .CW amd64
  262. kernels on Virtualbox,
  263. Vmware 7 on Ubuntu 12.04).
  264. .LP
  265. All of these bootstrap programs and the BIOS (and POST) can be avoided,
  266. once Plan 9 is running,
  267. by using
  268. .CW /dev/reboot
  269. as packaged up in
  270. .I fshalt (8),
  271. which is much faster.