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