bootboot.asm 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132
  1. ;*
  2. ;* x86_64-bios/bootboot.asm
  3. ;*
  4. ;* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
  5. ;*
  6. ;* Permission is hereby granted, free of charge, to any person
  7. ;* obtaining a copy of this software and associated documentation
  8. ;* files (the "Software"), to deal in the Software without
  9. ;* restriction, including without limitation the rights to use, copy,
  10. ;* modify, merge, publish, distribute, sublicense, and/or sell copies
  11. ;* of the Software, and to permit persons to whom the Software is
  12. ;* furnished to do so, subject to the following conditions:
  13. ;*
  14. ;* The above copyright notice and this permission notice shall be
  15. ;* included in all copies or substantial portions of the Software.
  16. ;*
  17. ;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. ;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. ;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. ;* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. ;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. ;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. ;* DEALINGS IN THE SOFTWARE.
  25. ;*
  26. ;* This file is part of the BOOTBOOT Protocol package.
  27. ;* @brief Booting code for BIOS, MultiBoot, El Torito, Linux boot
  28. ;*
  29. ;* Stage2 loader, compatible with GRUB and BIOS boot specification
  30. ;* 1.0.1 (even expansion ROM), El Torito "no emulation" CDROM boot,
  31. ;* as well as Linux boot protocol.
  32. ;*
  33. ;* text segment occupied: 800-7C00, bss: 8000-x
  34. ;*
  35. ;* Memory map
  36. ;* 0h - 600h reserved for the system
  37. ;* 600h - 800h stage1 (MBR/VBR, boot.bin)
  38. ;* 800h - 6C00h stage2 (this)
  39. ;* 6C00h - 7C00h stack (7000h - 700Fh SMP trampoline code)
  40. ;* 8000h - 9000h bootboot structure
  41. ;* 9000h - A000h environment
  42. ;* A000h - B000h disk buffer / PML4
  43. ;* B000h - C000h PDPE, higher half core 4K slots
  44. ;* C000h - D000h PDE 4K
  45. ;* D000h - E000h PTE 4K
  46. ;* E000h - F000h PDPE, 4G physical RAM identity mapped 2M
  47. ;* F000h - 10000h PDE 2M
  48. ;* 10000h - 11000h PDE 2M
  49. ;* 11000h - 12000h PDE 2M
  50. ;* 12000h - 13000h PDE 2M
  51. ;* 13000h - 14000h PTE 4K
  52. ;* 14000h - 9F000h core stacks (1k per core)
  53. ;*
  54. ;* At first big enough free hole, initrd. Usually at 1Mbyte.
  55. ;*
  56. ;* WARNING: supports BOOTBOOT Protocol level 1 only (static mappings)
  57. ;*
  58. BBDEBUG equ 1
  59. ;get Core boot parameter block
  60. include "bootboot.inc"
  61. ;VBE filter (available, has additional info, color, graphic, linear fb)
  62. VBE_MODEFLAGS equ 1+2+8+16+128
  63. ;*********************************************************************
  64. ;* Macros *
  65. ;*********************************************************************
  66. ;Writes a message on screen.
  67. macro real_print msg
  68. {
  69. if ~ msg eq si
  70. push si
  71. mov si, msg
  72. end if
  73. call real_printfunc
  74. if ~ msg eq si
  75. pop si
  76. end if
  77. }
  78. ;protected and real mode are functions, because we have to switch beetween
  79. macro real_protmode
  80. {
  81. USE16
  82. call near real_protmodefunc
  83. USE32
  84. }
  85. macro prot_realmode
  86. {
  87. USE32
  88. call near prot_realmodefunc
  89. USE16
  90. }
  91. ;edx:eax sector, edi:pointer
  92. macro prot_readsector
  93. {
  94. call near prot_readsectorfunc
  95. }
  96. macro prot_sleep delay
  97. {
  98. mov ecx, delay
  99. call near prot_sleepfunc
  100. }
  101. macro DBG msg
  102. {
  103. if BBDEBUG eq 1
  104. real_print msg
  105. end if
  106. }
  107. macro DBG32 msg
  108. {
  109. if BBDEBUG eq 1
  110. prot_realmode
  111. real_print msg
  112. real_protmode
  113. end if
  114. }
  115. virtual at 0
  116. bpb.jmp db 3 dup 0
  117. bpb.oem db 8 dup 0
  118. bpb.bps dw 0
  119. bpb.spc db 0
  120. bpb.rsc dw 0
  121. bpb.nf db 0 ;16
  122. bpb.nr dw 0
  123. bpb.ts16 dw 0
  124. bpb.media db 0
  125. bpb.spf16 dw 0 ;22
  126. bpb.spt dw 0
  127. bpb.nh dw 0
  128. bpb.hs dd 0
  129. bpb.ts32 dd 0
  130. bpb.spf32 dd 0 ;36
  131. bpb.flg dd 0
  132. bpb.rc dd 0 ;44
  133. bpb.vol db 6 dup 0
  134. bpb.fst db 8 dup 0 ;54
  135. bpb.dmy db 20 dup 0
  136. bpb.fst2 db 8 dup 0 ;84
  137. end virtual
  138. virtual at 0
  139. fatdir.name db 8 dup 0
  140. fatdir.ext db 3 dup 0
  141. fatdir.attr db 9 dup 0
  142. fatdir.ch dw 0
  143. fatdir.attr2 dd 0
  144. fatdir.cl dw 0
  145. fatdir.size dd 0
  146. end virtual
  147. ;*********************************************************************
  148. ;* header *
  149. ;*********************************************************************
  150. ;offs len desc
  151. ; 0 2 expansion ROM magic (AA55h)
  152. ; 2 1 size in blocks (40h)
  153. ; 3 1 magic E9h
  154. ; 4 2 real mode entry point (relative)
  155. ; 6 2 checksum
  156. ; 8 8 magic 'BOOTBOOT'
  157. ; 16 10 zeros, at least one and a padding
  158. ; 26 2 pnp ptr, must be zero
  159. ; 28 4 flags, must be zero
  160. ; 32 32 MultiBoot header with protected mode entry point
  161. ; 64 x free to use
  162. ;497 127 Linux x86 boot protocol header
  163. ;any format can follow.
  164. USE16
  165. ORG 800h
  166. ;BOOTBOOT stage2 header (64 bytes)
  167. loader: db 55h,0AAh ;ROM magic
  168. db (loader_end-loader)/512 ;size in 512 blocks
  169. .executor: jmp near realmode_start ;entry point
  170. .checksum: dw 0 ;checksum
  171. .name: db "BOOTBOOT"
  172. dw 0
  173. dd 0, 0
  174. .pnpptr: dw 0
  175. .flags: dd 0
  176. MB_MAGIC equ 01BADB002h
  177. MB_FLAGS equ 010001h
  178. align 8
  179. .mb_header: dd MB_MAGIC ;magic
  180. dd MB_FLAGS ;flags
  181. dd -(MB_MAGIC+MB_FLAGS) ;checksum (0-magic-flags)
  182. dd .mb_header ;our location (GRUB should load us here)
  183. dd 0800h ;the same... load start
  184. dd 07C00h ;load end
  185. dd 0h ;no bss
  186. dd multiboot_start ;entry point
  187. ;no segments or sections, code comes right after the header
  188. ;*********************************************************************
  189. ;* code *
  190. ;*********************************************************************
  191. ;----------------Multiboot stub-----------------
  192. USE32
  193. multiboot_start:
  194. cli
  195. cld
  196. ;clear drive code, initrd ptr and environment
  197. xor edx, edx
  198. mov edi, 9000h
  199. mov dword [edi], edx
  200. mov dword [bootboot.initrd_ptr], edx
  201. mov dword [bootboot.initrd_size], edx
  202. ;no GRUB environment available?
  203. cmp eax, 2BADB002h
  204. jne @f
  205. ;save drive code for boot device
  206. mov dl, byte [ebx+12]
  207. ;is there a module? mod_count!=0
  208. cmp dword [ebx+20], 0
  209. jz @f
  210. ;mod_addr!=0
  211. mov eax, dword [ebx+24]
  212. or eax, eax
  213. jz @f
  214. ;mods[0].end
  215. mov ecx, dword [eax+4]
  216. sub ecx, dword [eax]
  217. mov dword [bootboot.initrd_size], ecx
  218. ;mods[0].start
  219. mov ecx, dword [eax]
  220. mov dword [bootboot.initrd_ptr], ecx
  221. inc byte [hasinitrd]
  222. ;mod_count>1?
  223. cmp dword [ebx+20], 1
  224. jbe @f
  225. ;mods[1], copy environment (4k)
  226. mov esi, dword [eax+16]
  227. mov ecx, 1024
  228. repnz movsd
  229. inc byte [hasconfig]
  230. @@: lgdt [GDT_value]
  231. mov ax, DATA_BOOT ;clear shadow segment registers
  232. mov ds, ax
  233. mov es, ax
  234. mov ss, ax
  235. xor esp, esp ;GRUB leaves the upper 16 bits non-zero, we must clear it
  236. jmp CODE_BOOT:.real ;load 16 bit mode segment into cs
  237. USE16
  238. .real: mov eax, CR0
  239. and eax, 07FFFFFFEh ;switching back to real mode
  240. mov CR0, eax
  241. xor ax, ax
  242. mov ds, ax ;load segment registers DS and CS
  243. jmp 0:@f
  244. @@: lidt [idt16] ;restore IDT as newer GRUBs mess it up
  245. ;fallthrough realmode_start
  246. ;-----------realmode-protmode stub-------------
  247. realmode_start:
  248. cli
  249. cld
  250. mov sp, 7C00h
  251. xor ax, ax
  252. mov es, ax
  253. mov ss, ax
  254. ;relocate ourself from ROM to RAM if necessary
  255. call .getaddr
  256. .getaddr: pop si
  257. mov ax, cs
  258. or ax, ax
  259. jnz .reloc
  260. cmp si, .getaddr
  261. je .noreloc
  262. .reloc: mov ds, ax
  263. mov di, loader
  264. sub si, .getaddr-loader
  265. mov cx, (loader_end-loader)/2
  266. repnz movsw
  267. xor ax, ax
  268. mov ds, ax
  269. jmp 0:.clrdl
  270. .noreloc: or dl, dl
  271. jnz @f
  272. .clrdl: mov dl, 80h
  273. @@: mov byte [bootdev], dl
  274. ;get CDROM drive code
  275. mov ax, word 4B01h
  276. mov si, entrypoint ; bss area
  277. mov byte [si + 2], 0E0h
  278. push si
  279. int 13h
  280. pop si
  281. jc @f
  282. mov al, byte [si + 2]
  283. mov byte [cdromdev], al
  284. @@:
  285. ;-----initialize serial port COM1,115200,8N1------
  286. ; mov ax, 0401h
  287. ; xor bx, bx
  288. ; mov cx, 030Bh
  289. ; xor dx, dx
  290. ; int 14h
  291. mov dx, word [400h]
  292. or dx, dx
  293. jnz @f
  294. ; if the IO port isn't set, try the default one of COM1
  295. mov dx, 3f8h
  296. mov word [400h], dx
  297. ; initialize the serial outselves, because Bochs BIOS is buggy
  298. @@: call serialsetup
  299. ; if there's no serial, but BIOS incorrectly sets the IO port for it
  300. mov dx, word [400h]
  301. add dx, 5
  302. in al, dx
  303. cmp al, 0FFh
  304. jne @f
  305. mov word [400h], 0
  306. @@: real_print starting
  307. ; flush PS/2 keyboard
  308. in al, 060h ; read key
  309. in al, 061h ; ack
  310. out 061h, al
  311. DBG dbg_cpu
  312. ;-----check CPU-----
  313. ;at least 286?
  314. pushf
  315. pushf
  316. pop dx
  317. xor dh,40h
  318. push dx
  319. popf
  320. pushf
  321. pop bx
  322. popf
  323. cmp dx, bx
  324. jne .cpuerror
  325. mov ebp, 200000h
  326. ;check for 386
  327. ;look for cpuid instruction
  328. pushfd
  329. pop eax
  330. mov ebx, eax
  331. xor eax, ebp
  332. and ebx, ebp
  333. push eax
  334. popfd
  335. pushfd
  336. pop eax
  337. and eax, ebp
  338. xor eax, ebx
  339. shr eax, 21
  340. and al, 1
  341. jz .cpuerror
  342. ;ok, now we can get cpu feature flags
  343. mov eax, 1
  344. cpuid
  345. shr al, 4
  346. shr ebx, 24
  347. mov word [bootboot.bspid], bx
  348. ;look for minimum family
  349. cmp ax, 0600h
  350. jb .cpuerror
  351. ;look for minimum feature flags
  352. ;do we have PAE?
  353. bt edx, 6
  354. jnc .cpuerror
  355. ;what about MSR?
  356. bt edx, 5
  357. jnc .cpuerror
  358. ;do we have RDTSC instruction?
  359. bt edx, 4
  360. jnc .cpuerror
  361. ;and can we use long mode (LME)?
  362. mov eax, 80000000h
  363. mov ebp, eax
  364. inc ebp
  365. cpuid
  366. cmp eax, ebp
  367. jb .cpuerror
  368. mov eax, ebp
  369. cpuid
  370. ;long mode
  371. bt edx, 29
  372. jc cpuok
  373. .cpuerror: mov si, noarch
  374. jmp real_diefunc
  375. ;okay, we can do 64 bit!
  376. ;--- Linux x86 boot protocol header ---
  377. db 01F1h-($-$$) dup 090h
  378. hdr:
  379. setup_sects: db (loader_end-loader-511)/512
  380. root_flags: dw 0
  381. syssize: dd (loader_end-loader)/16
  382. ram_size: dw 0
  383. vid_mode: dw 0
  384. root_dev: dw 0
  385. boot_flag: dw 0AA55h
  386. db 0EBh ; short jmp
  387. db start_of_setup-@f ; no space to jump to realmode_start directly
  388. @@: db "HdrS"
  389. dw 020eh
  390. realmode_swtch: dd 0
  391. start_sys_seg: dw 0
  392. dw 0 ; we don't have Linux kernel version...
  393. type_of_loader: db 0FFh
  394. loadflags: db 0
  395. setup_move_size: dw 08000h
  396. code32_start: dd 0 ; we dont' use this either...
  397. ramdisk_image: dd 0
  398. ramdisk_size: dd 0
  399. bootsect_kludge: dd 0
  400. heap_end_ptr: dd loader_end+1024-512 ; we don't care, we set our stack directly
  401. ext_loader_ver: db 0
  402. ext_loader_type: db 0
  403. cmd_line_ptr: dd 0
  404. initrd_addr_max: dd 07fffffffh
  405. kernel_alignment: dd 16
  406. relocatable_kernel: db 0
  407. min_alignment: db 4
  408. xloadflags: dw 0
  409. cmdline_size: dd 0
  410. hardware_subarch: dd 0
  411. hardware_subarch_data: dq 0
  412. payload_offset: dd 0
  413. payload_length: dd 0
  414. setup_data: dq 0
  415. pref_address: dq 90000h ; qemu does not handle anything else
  416. init_size: dd loader_end-loader
  417. handover_offset: dd 0
  418. acpi_rsdp_addr: dq 0
  419. start_of_setup:
  420. ; fix: qemu forces address and set CS to 0x9020, but we must jump to segment 0x9000.
  421. jmp 9000h:realmode_start-loader
  422. ; --- end of Linux boot protocol header ---
  423. serialsetup:
  424. inc dx
  425. xor al, al
  426. out dx, al ; IER int off
  427. mov al, 80h
  428. add dx, 2
  429. out dx, al ; LCR set divisor mode
  430. mov al, 1
  431. sub dx, 3
  432. out dx, al ; DLL divisor lo 115200
  433. xor al, al
  434. inc dx
  435. out dx, al ; DLH divisor hi
  436. inc dx
  437. out dx, al ; FCR fifo off
  438. mov al, 43h
  439. inc dx
  440. out dx, al ; LCR 8N1, break on
  441. mov al, 8
  442. inc dx
  443. out dx, al ; MCR Aux out 2
  444. xor al, al
  445. sub dx, 4
  446. in al, dx ; clear receiver/transmitter
  447. ret
  448. cpuok: DBG dbg_A20
  449. ;-----enable A20-----
  450. ;no problem even if a20 is already turned on.
  451. mov ax, 2401h ;BIOS enable A20 function
  452. int 15h
  453. ;see if it worked
  454. call a20chk
  455. jz a20ok
  456. ;keyboard nightmare
  457. call a20wait
  458. mov al, 0ADh
  459. out 64h, al
  460. call a20wait
  461. mov al, 0D0h
  462. out 64h, al
  463. call a20wait2
  464. in al, 60h
  465. push ax
  466. call a20wait
  467. mov al, 0D1h
  468. out 64h, al
  469. call a20wait
  470. pop ax
  471. or al, 2
  472. out 60h, al
  473. call a20wait
  474. mov al, 0AEh
  475. out 64h, al
  476. call a20wait
  477. call a20chk
  478. jz a20ok
  479. ;fast enable method
  480. in al, 92h
  481. test al, 2
  482. jnz a20ok
  483. or al, 2
  484. and al, 0FEh
  485. out 92h, al
  486. jmp a20ok
  487. a20chk: push es
  488. xor ax, ax
  489. dec ax
  490. mov es, ax
  491. mov ah, byte [es:510h]
  492. mov byte [ds:500h], 0
  493. mov byte [es:510h], al
  494. mov al, byte [ds:500h]
  495. mov byte [es:510h], ah
  496. pop es
  497. or al, al
  498. ret
  499. a20wait: in al, 64h
  500. test al, 2
  501. jnz a20wait
  502. ret
  503. a20wait2: in al, 64h
  504. test al, 1
  505. jz a20wait2
  506. ret
  507. a20ok:
  508. ; calibrate RDTSC
  509. rdtsc
  510. mov dword [ncycles], eax
  511. mov dword [ncycles+4], edx
  512. ; wait 200 usec
  513. xor cx, cx
  514. mov dx, 200
  515. mov ah, 086h
  516. int 15h
  517. rdtsc
  518. sub eax, dword [ncycles]
  519. sbb edx, dword [ncycles+4]
  520. mov dword [ncycles], eax
  521. mov dword [ncycles+4], edx
  522. ; wait for a key press for half a sec, if pressed use backup initrd
  523. mov word [origcount], 0
  524. sti
  525. .waitkey: mov ax, word 0100h
  526. or al, al ; make sure ZF is clear
  527. int 16h
  528. jz @f
  529. or al, al
  530. jz @f
  531. ; this blocks, so only call it if we are sure there's a keystroke waiting
  532. xor ah, ah
  533. int 16h
  534. mov eax, ' BAK'
  535. mov dword [bkp], eax
  536. real_print backup
  537. jmp .waitend
  538. @@: ; wait 10 millisec
  539. xor cx, cx
  540. mov dx, 10000
  541. mov ah, 086h
  542. int 15h
  543. ; repeat loop 50 times
  544. inc word [origcount]
  545. cmp word [origcount], 50
  546. jl .waitkey
  547. .waitend: cli
  548. ;-----detect memory map-----
  549. getmemmap:
  550. DBG dbg_mem
  551. xor eax, eax
  552. mov edi, bootboot.acpi_ptr
  553. mov ecx, 16
  554. repnz stosd
  555. cmp byte [hasconfig], 0
  556. jnz @f
  557. mov dword [9000h], eax
  558. @@: cmp byte [hasinitrd], 0
  559. jnz @f
  560. mov dword [bootboot.initrd_ptr], eax
  561. mov dword [bootboot.initrd_size], eax
  562. @@: mov dword [bootboot.initrd_ptr+4], eax
  563. mov dword [bootboot.initrd_size+4], eax
  564. mov eax, bootboot_MAGIC
  565. mov dword [bootboot.magic], eax
  566. mov dword [bootboot.size], 128
  567. mov dword [bootboot.protocol], PROTOCOL_STATIC or LOADER_BIOS
  568. mov di, bootboot.fb_ptr
  569. mov cx, 800h-28h
  570. xor ax, ax
  571. repnz stosw
  572. mov di, bootboot.mmap
  573. xor ebx, ebx
  574. clc
  575. .nextmap: cmp word [bootboot.size], 4096
  576. jae .nomoremap
  577. mov edx, 'PAMS'
  578. xor ecx, ecx
  579. mov cl, 20
  580. xor eax, eax
  581. mov ax, 0E820h
  582. int 15h
  583. jc .nomoremap
  584. cmp eax, 'PAMS'
  585. jne .nomoremap
  586. ;is this the first memory hole? If so, mark
  587. ;ourself as reserved memory
  588. cmp dword [di+4], 0
  589. jnz .notfirst
  590. cmp dword [di], 0
  591. jnz .notfirst
  592. ; "allocate" memory for loader
  593. mov eax, 14000h
  594. add dword [di], eax
  595. sub dword [di+8], eax
  596. ;convert E820 memory type to BOOTBOOT memory type
  597. .notfirst: mov al, byte [di+16]
  598. cmp al, 1
  599. je .noov
  600. cmp al, 4
  601. je .isacpi
  602. cmp al, 3
  603. jne @f
  604. .isacpi: mov al, MMAP_ACPI
  605. jmp .noov
  606. ; everything else reserved
  607. @@: mov al, MMAP_USED
  608. .noov: ;copy memory type to size's least significant byte
  609. mov byte [di+8], al
  610. xor ecx, ecx
  611. ;is it ACPI area?
  612. cmp al, MMAP_ACPI
  613. jne .notacpi
  614. mov dword [bootboot.acpi_ptr], edi
  615. jmp .entryok
  616. ;is it free slot?
  617. .notacpi: cmp al, MMAP_FREE
  618. jne .notmax
  619. .freemem: ;do we have a ramdisk area?
  620. cmp dword [bootboot.initrd_ptr], 0
  621. jnz .entryok
  622. ;is it big enough for the compressed and the inflated ramdisk?
  623. mov ebp, (INITRD_MAXSIZE+2)*1024*1024
  624. shr ebp, 20
  625. shl ebp, 20
  626. ;is this free memory hole big enough? (first fit)
  627. .sizechk: mov eax, dword [di+8] ;load size
  628. xor al, al
  629. mov edx, dword [di+12]
  630. and edx, 000FFFFFFh
  631. or edx, edx
  632. jnz .bigenough
  633. cmp eax, ebp
  634. jb .entryok
  635. .bigenough: mov eax, dword [di]
  636. ;save ramdisk pointer
  637. mov dword [bootboot.initrd_ptr], eax
  638. .entryok: ;get limit of memory
  639. mov eax, dword [di+8] ;load size
  640. and al, 0F0h ;clear lower tetrad for type
  641. mov edx, dword [di+12]
  642. add eax, dword [di] ;add base
  643. adc edx, dword [di+4]
  644. and edx, 000FFFFFFh
  645. .notmax: add dword [bootboot.size], 16
  646. ;bubble up entry if necessary
  647. push si
  648. push di
  649. .bubbleup: mov si, di
  650. cmp di, bootboot.mmap
  651. jbe .swapdone
  652. sub di, 16
  653. ;order by base asc
  654. mov eax, dword [si+4]
  655. cmp eax, dword [di+4]
  656. jb .swapmodes
  657. jne .swapdone
  658. mov eax, dword [si]
  659. cmp eax, dword [di]
  660. jae .swapdone
  661. .swapmodes: push di
  662. mov cx, 16/2
  663. @@: mov dx, word [di]
  664. lodsw
  665. stosw
  666. mov word [si-2], dx
  667. dec cx
  668. jnz @b
  669. pop di
  670. jmp .bubbleup
  671. .swapdone: pop di
  672. pop si
  673. add di, 16
  674. cmp di, bootboot.mmap+4096
  675. jae .nomoremap
  676. .skip: or ebx, ebx
  677. jnz .nextmap
  678. .nomoremap: cmp dword [bootboot.size], 128
  679. jne .E820ok
  680. .noE820: mov si, memerr
  681. jmp real_diefunc
  682. .E820ok: ;check if we have memory for the ramdisk
  683. xor ecx, ecx
  684. cmp dword [bootboot.initrd_ptr], ecx
  685. jnz .enoughmem
  686. .nomem: mov si, noenmem
  687. jmp real_diefunc
  688. .enoughmem:
  689. ;-----detect system structures-----
  690. DBG dbg_systab
  691. ;do we need that scanning shit?
  692. mov eax, dword [bootboot.acpi_ptr]
  693. or eax, eax
  694. jz @f
  695. shr eax, 4
  696. mov es, ax
  697. ;no if E820 map was correct
  698. cmp dword [es:0], 'XSDT'
  699. je .detsmbi
  700. cmp dword [es:0], 'RSDT'
  701. je .detsmbi
  702. @@: inc dx
  703. ;get starting address min(EBDA,E0000)
  704. mov ah,0C1h
  705. stc
  706. int 15h
  707. mov bx, es
  708. jnc @f
  709. mov ax, [ebdaptr]
  710. @@: cmp ax, 0E000h
  711. jb .acpinext
  712. mov ax, 0E000h
  713. ;detect ACPI ptr
  714. .acpinext: mov es, ax
  715. cmp dword [es:0], 'RSD '
  716. jne .acpinotf
  717. cmp dword [es:4], 'PTR '
  718. jne .acpinotf
  719. ;ptr found
  720. ; do we have XSDT?
  721. cmp dword [es:28], 0
  722. jne .acpi2
  723. cmp dword [es:24], 0
  724. je .acpi1
  725. .acpi2: mov eax, dword [es:24]
  726. mov dword [bootboot.acpi_ptr], eax
  727. mov edx, dword [es:28]
  728. mov dword [bootboot.acpi_ptr+4], edx
  729. jmp .chkacpi
  730. ; no, fallback to RSDT
  731. .acpi1: mov eax, dword [es:16]
  732. @@: mov dword [bootboot.acpi_ptr], eax
  733. xor edx, edx
  734. jmp .chkacpi
  735. .acpinotf: xor eax, eax
  736. mov ax, es
  737. inc ax
  738. cmp ax, 0A000h
  739. jne @f
  740. add ax, 03000h
  741. @@: ;end of 1Mb?
  742. or ax, ax
  743. jnz .acpinext
  744. mov si, noacpi
  745. jmp real_diefunc
  746. .chkacpi: ; check if memory is marked as ACPI in the memory map
  747. mov esi, bootboot.mmap
  748. mov edi, bootboot.magic
  749. add edi, dword [bootboot.size]
  750. .nextmm: cmp edx, dword [si+4]
  751. jne .skipmm
  752. mov ebx, dword [si]
  753. cmp eax, ebx
  754. jl .skipmm
  755. add ebx, dword [si+8]
  756. and bl, 0F0h
  757. cmp eax, ebx
  758. jge .skipmm
  759. mov al, byte [si+8]
  760. and al, 0F0h
  761. or al, MMAP_ACPI
  762. mov byte [si+8], al
  763. jmp .detsmbi
  764. .skipmm: add si, 16
  765. cmp si, di
  766. jl .nextmm
  767. ;detect SMBios tables
  768. .detsmbi: xor eax, eax
  769. mov ax, 0E000h
  770. xor dx, dx
  771. .smbnext: mov es, ax
  772. push ax
  773. cmp dword [es:0], '_SM_'
  774. je .smbfound
  775. cmp dword [es:0], '_MP_'
  776. jne .smbnotf
  777. shl eax, 4
  778. mov dword [bootboot.mp_ptr], eax
  779. bts dx, 2
  780. jmp .smbnotf
  781. .smbfound: shl eax, 4
  782. mov dword [bootboot.smbi_ptr], eax
  783. bts dx, 1
  784. .smbnotf: pop ax
  785. bt ax, 0
  786. mov bx, ax
  787. and bx, 03h
  788. inc ax
  789. ;end of 1Mb?
  790. or ax, ax
  791. jnz .smbnext
  792. ;restore ruined es
  793. .detend: push ds
  794. pop es
  795. DBG dbg_time
  796. ; ------- BIOS date and time -------
  797. mov ah, 4
  798. int 1Ah
  799. jc .nobtime
  800. ;ch century
  801. ;cl year
  802. xchg ch, cl
  803. mov word [bootboot.datetime], cx
  804. ;dh month
  805. ;dl day
  806. xchg dh, dl
  807. mov word [bootboot.datetime+2], dx
  808. mov ah, 2
  809. int 1Ah
  810. jc .nobtime
  811. ;ch hour
  812. ;cl min
  813. xchg ch, cl
  814. mov word [bootboot.datetime+4], cx
  815. ;dh sec
  816. ;dl daylight saving on/off
  817. xchg dh, dl
  818. mov word [bootboot.datetime+6], dx
  819. .nobtime:
  820. ;---- enable protmode ----
  821. cli
  822. cld
  823. lgdt [GDT_value]
  824. mov eax, cr0
  825. or al, 1
  826. mov cr0, eax
  827. jmp CODE_PROT:protmode_start
  828. ;---- enable protmode on APs ----
  829. ap_trampoline:
  830. ;--this code will be relocated to the SIPI address --
  831. cli
  832. cld
  833. jmp 0:ap_start
  834. ;--relocation end--
  835. ap_start: xor ax, ax
  836. mov ds, ax
  837. lgdt [GDT_value]
  838. mov eax, cr0
  839. or al, 1
  840. mov cr0, eax
  841. jmp CODE_PROT:ap_prot
  842. USE32
  843. ap_prot: mov ax, DATA_PROT
  844. mov ds, ax
  845. mov es, ax
  846. mov fs, ax
  847. mov gs, ax
  848. mov ss, ax
  849. ; enable Local APIC
  850. mov esi, dword [lapic_ptr]
  851. mov eax, dword [esi + 0F0h]
  852. or ah, 1
  853. mov dword [esi + 0F0h], eax
  854. mov ecx, 1Bh ; enable APIC MSR
  855. rdmsr
  856. bt eax, 1
  857. wrmsr
  858. lock inc word [ap_done]
  859. ; spinlock until BSP finishes
  860. @@: pause
  861. cmp byte [bsp_done], 0
  862. jz @b
  863. jmp longmode_init
  864. ;writes the reason, waits for a key and reboots.
  865. prot_diefunc:
  866. prot_realmode
  867. USE16
  868. real_diefunc:
  869. xor ax, ax
  870. mov ds, ax
  871. push si
  872. real_print loader.name
  873. real_print panic
  874. pop si
  875. call real_printfunc
  876. mov si, crlf
  877. call real_printfunc
  878. call real_getchar
  879. mov al, 0FEh
  880. out 64h, al
  881. jmp far 0FFFFh:0 ;invoke BIOS POST routine
  882. ; get a character from keyboard or from serial line
  883. real_getchar:
  884. pushf
  885. sti
  886. push si
  887. push di
  888. .chkser: cmp word [400h], 0
  889. jz @f
  890. mov ah, byte 03h
  891. xor dx, dx
  892. int 14h
  893. bt ax, 8
  894. jnc @f
  895. mov ah, byte 02h
  896. xor dx, dx
  897. int 14h
  898. jmp .gotch
  899. @@: mov ah, byte 01h
  900. int 16h
  901. jz .chkser
  902. xor ah, ah
  903. int 16h
  904. .gotch: pop di
  905. pop si
  906. popf
  907. xor ah, ah
  908. ret
  909. ;ds:si zero terminated string to write
  910. real_printfunc:
  911. lodsb
  912. or al, al
  913. jz .end
  914. ;out 0e9h, al
  915. push si
  916. push ax
  917. mov ah, byte 0Eh
  918. mov bx, word 11
  919. int 10h
  920. pop ax
  921. cmp word [400h], 0
  922. jz @f
  923. mov ah, byte 01h
  924. xor dx, dx
  925. int 14h
  926. ;if BIOS timed out, clear the IO address
  927. ;so that further calls won't try sending
  928. and ah, 80h
  929. jz @f
  930. mov word[400h], 0
  931. @@: pop si
  932. jmp real_printfunc
  933. .end: ret
  934. real_protmodefunc:
  935. cli
  936. ;get return address
  937. xor ebp, ebp
  938. pop bp
  939. mov dword [hw_stack], esp
  940. lgdt [GDT_value]
  941. mov eax, cr0 ;enable protected mode
  942. or al, 1
  943. mov cr0, eax
  944. jmp CODE_PROT:.init
  945. USE32
  946. .init: mov ax, DATA_PROT
  947. mov ds, ax
  948. mov es, ax
  949. mov fs, ax
  950. mov gs, ax
  951. mov ss, ax
  952. mov esp, dword [hw_stack]
  953. jmp ebp
  954. prot_realmodefunc:
  955. cli
  956. ;get return address
  957. pop ebp
  958. ;save stack pointer
  959. mov dword [hw_stack], esp
  960. jmp CODE_BOOT:.back ;load 16 bit mode segment into cs
  961. USE16
  962. .back: mov eax, CR0
  963. and al, 0FEh ;switching back to real mode
  964. mov CR0, eax
  965. xor ax, ax
  966. mov ds, ax ;load registers 2nd turn
  967. mov es, ax
  968. mov ss, ax
  969. jmp 0:.back2
  970. .back2: mov sp, word [hw_stack]
  971. sti
  972. jmp bp
  973. USE32
  974. prot_readsectorfunc:
  975. push eax
  976. push ecx
  977. push esi
  978. push edi
  979. ;load 8 sectors (1 page) or more in low memory
  980. mov dword [lbapacket.sect0], eax
  981. prot_realmode
  982. ;try all drives from bootdev-87 to support RAID mirror
  983. mov dl, byte [bootdev]
  984. mov byte [readdev], dl
  985. mov byte [cntdev], 0
  986. mov byte [iscdrom], 0
  987. .again: mov ax, word [lbapacket.count]
  988. mov word [origcount], ax
  989. mov dl, byte [readdev]
  990. cmp dl, byte [cdromdev]
  991. jl @f
  992. ;use 2048 byte sectors instead of 512 if it's a cdrom
  993. mov al, byte [lbapacket.sect0]
  994. and al, 011b
  995. or al, al
  996. jz .cdok
  997. ;this should never happen.
  998. ; - GPT is loaded from PMBR, from LBA 0 (%4==0)
  999. ; - ESP is at LBA 128 or 2048 (%4==0)
  1000. ; - root dir is at LBA 172 (%4==0) for FAT16, and it's cluster aligned for FAT32
  1001. ; - cluster size is multiple of 4 sectors
  1002. mov si, notcdsect
  1003. jmp real_diefunc
  1004. .cdok: shr dword [lbapacket.sect0], 2
  1005. add word [lbapacket.count], 3
  1006. shr word [lbapacket.count], 2
  1007. mov byte [iscdrom], 1
  1008. @@: mov ah, byte 42h
  1009. mov esi, lbapacket
  1010. clc
  1011. int 13h
  1012. jnc .rdok
  1013. ;we do not expect this to fail, but if so, load sector from another
  1014. ;drive assuming we have a RAID mirror. This will fail for non-RAIDs
  1015. mov al, byte [readdev]
  1016. inc al
  1017. cmp al, 87h
  1018. jle @f
  1019. mov al, 80h
  1020. @@: mov byte [readdev], al
  1021. inc byte [cntdev]
  1022. cmp byte [cntdev], 8
  1023. jle .again
  1024. .rdok: xor ebx, ebx
  1025. mov bl, ah
  1026. real_protmode
  1027. pop edi
  1028. or edi, edi
  1029. jz @f
  1030. push edi
  1031. ;and copy to addr where it wanted to be (maybe in high memory)
  1032. mov esi, dword [lbapacket.addr]
  1033. xor ecx, ecx
  1034. mov cx, word [origcount]
  1035. shl ecx, 7
  1036. repnz movsd
  1037. pop edi
  1038. @@: pop esi
  1039. pop ecx
  1040. pop eax
  1041. ret
  1042. prot_hex2bin:
  1043. xor eax, eax
  1044. xor ebx, ebx
  1045. @@: mov bl, byte [esi]
  1046. cmp bl, '0'
  1047. jb @f
  1048. cmp bl, '9'
  1049. jbe .num
  1050. cmp bl, 'A'
  1051. jb @f
  1052. cmp bl, 'F'
  1053. ja @f
  1054. sub bl, 7
  1055. .num: sub bl, '0'
  1056. shl eax, 4
  1057. add eax, ebx
  1058. inc esi
  1059. dec cx
  1060. jnz @b
  1061. @@: ret
  1062. prot_dec2bin:
  1063. xor eax, eax
  1064. xor ebx, ebx
  1065. xor edx, edx
  1066. mov ecx, 10
  1067. @@: mov bl, byte [esi]
  1068. cmp bl, '0'
  1069. jb @f
  1070. cmp bl, '9'
  1071. ja @f
  1072. mul ecx
  1073. sub bl, '0'
  1074. add eax, ebx
  1075. inc esi
  1076. jmp @b
  1077. @@: ret
  1078. ;IN: eax=str ptr, ecx=length OUT: eax=num
  1079. prot_oct2bin:
  1080. push ebx
  1081. push edx
  1082. mov ebx, eax
  1083. xor eax, eax
  1084. xor edx, edx
  1085. @@: shl eax, 3
  1086. mov dl, byte[ebx]
  1087. sub dl, '0'
  1088. add eax, edx
  1089. inc ebx
  1090. dec ecx
  1091. jnz @b
  1092. pop edx
  1093. pop ebx
  1094. ret
  1095. ; IN: ecx delay time in 200 usec units
  1096. prot_sleepfunc:
  1097. push edx
  1098. rdtsc
  1099. mov dword [gpt_ptr], eax
  1100. mov dword [gpt_ptr+4], edx
  1101. mov eax, dword [ncycles]
  1102. mov edx, dword [ncycles+4]
  1103. mul ecx
  1104. add dword [gpt_ptr], eax
  1105. adc dword [gpt_ptr+4], edx
  1106. @@: pause
  1107. rdtsc
  1108. cmp dword [gpt_ptr+4], edx
  1109. jl @b
  1110. cmp dword [gpt_ptr], eax
  1111. jl @b
  1112. pop edx
  1113. ret
  1114. ; IN: al, character to send
  1115. uart_send: mov ah, al
  1116. mov dx, word [400h] ;3fdh
  1117. add dx, 5
  1118. @@: pause
  1119. in al, dx
  1120. and al, 20h
  1121. jz @b
  1122. sub dx, 5
  1123. mov al, ah
  1124. out dx, al
  1125. ret
  1126. ; IN: edi pointer to store the received char
  1127. uart_getc: mov dx, word [400h] ;3fdh
  1128. add dx, 5
  1129. @@: pause
  1130. in al, dx
  1131. and al, 1
  1132. jz @b
  1133. sub dl, 5
  1134. in al, dx
  1135. stosb
  1136. ret
  1137. protmode_start:
  1138. mov ax, DATA_PROT
  1139. mov ds, ax
  1140. mov es, ax
  1141. mov fs, ax
  1142. mov gs, ax
  1143. mov ss, ax
  1144. mov esp, 7C00h
  1145. ; ------- Locate initrd --------
  1146. cmp byte [hasinitrd], 0
  1147. jnz .initrdrom
  1148. mov esi, 0C8000h
  1149. .nextrom: cmp word [esi], 0AA55h
  1150. jne @f
  1151. cmp dword [esi+8], 'INIT'
  1152. jne @f
  1153. cmp word [esi+12], 'RD'
  1154. jne @f
  1155. mov ecx, dword [esi+16]
  1156. mov dword [bootboot.initrd_size], ecx
  1157. add esi, 32
  1158. cmp word [esi], 08b1fh
  1159. je .initrdrom
  1160. ; copy from ROM to RAM
  1161. mov edi, dword [bootboot.initrd_ptr]
  1162. repnz movsb
  1163. jmp .noinflate
  1164. @@: add esi, 2048
  1165. cmp esi, 0F4000h
  1166. jb .nextrom
  1167. ;---- notify raspbootcom / USBImager to send the initrd over serial line ----
  1168. cmp word [400h], 0
  1169. jz .getgpt
  1170. mov al, 3
  1171. call uart_send
  1172. call uart_send
  1173. call uart_send
  1174. ; wait for response with timeout
  1175. mov ah, al
  1176. mov cx, 10000
  1177. mov dx, word [400h]
  1178. add dx, 5
  1179. @@: dec cx
  1180. jz .getgpt
  1181. pause
  1182. in al, dx
  1183. and al, 1
  1184. jz @b
  1185. DBG32 dbg_serial
  1186. ; read the initrd's size
  1187. mov edi, bootboot.initrd_size
  1188. call uart_getc
  1189. call uart_getc
  1190. call uart_getc
  1191. call uart_getc
  1192. mov ecx, dword [bootboot.initrd_size]
  1193. ; send negative or positive acknowledge
  1194. cmp ecx, 32
  1195. jb .se
  1196. cmp ecx, INITRD_MAXSIZE*1024*1024
  1197. jb .ok
  1198. .se: mov al, 'S'
  1199. call uart_send
  1200. mov al, 'E'
  1201. call uart_send
  1202. jmp .getgpt
  1203. .ok: mov al, 'O'
  1204. call uart_send
  1205. mov al, 'K'
  1206. call uart_send
  1207. mov edi, dword [bootboot.initrd_ptr]
  1208. ; read in the image
  1209. @@: call uart_getc
  1210. dec ecx
  1211. jnz @b
  1212. jmp .initrdloaded
  1213. ;---- read GPT -----
  1214. .getgpt: xor eax, eax
  1215. xor edi, edi
  1216. prot_readsector
  1217. if BBDEBUG eq 1
  1218. cmp byte [iscdrom], 0
  1219. jz @f
  1220. DBG32 dbg_cdrom
  1221. jmp .isgpt
  1222. @@: DBG32 dbg_gpt
  1223. .isgpt:
  1224. end if
  1225. mov esi, 0A000h+512
  1226. cmp dword [esi], 'EFI '
  1227. je @f
  1228. .nogpt: mov esi, nogpt
  1229. jmp prot_diefunc
  1230. @@: mov edi, 0B000h
  1231. mov ebx, edi
  1232. mov ecx, 896
  1233. repnz movsd
  1234. mov esi, ebx
  1235. mov ecx, dword [esi+80] ;number of entries
  1236. mov ebx, dword [esi+84] ;size of one entry
  1237. add esi, 512
  1238. mov edx, esi ;first entry
  1239. mov dword [gpt_ent], ebx
  1240. mov dword [gpt_num], ecx
  1241. mov dword [gpt_ptr], edx
  1242. ; first, look for a partition with bootable flag
  1243. mov esi, edx
  1244. @@: cmp dword [esi], 0 ;failsafe, jump to parttype search
  1245. jne .notz
  1246. cmp dword [esi+32], 0
  1247. jz .nextgpt
  1248. .notz: bt word [esi+48], 2 ;EFI_PART_USED_BY_OS?
  1249. jc .loadesp2
  1250. add esi, ebx
  1251. dec ecx
  1252. jnz @b
  1253. ; if none, look for specific partition types
  1254. .nextgpt: mov esi, dword [gpt_ptr]
  1255. mov ebx, dword [gpt_ent]
  1256. mov ecx, dword [gpt_num]
  1257. mov eax, 0C12A7328h
  1258. mov edx, 011D2F81Fh
  1259. @@: cmp dword [esi], eax ;GUID match?
  1260. jne .note
  1261. cmp dword [esi+4], edx
  1262. je .loadesp
  1263. .note: cmp dword [esi], 'OS/Z' ;or OS/Z root partition for this architecture?
  1264. jne .noto
  1265. cmp word [esi+4], 08664h
  1266. jne .noto
  1267. cmp dword [esi+12], 'root'
  1268. je .loadesp
  1269. .noto: add esi, ebx
  1270. dec ecx
  1271. jnz @b
  1272. .nopart: mov esi, nopar
  1273. jmp prot_diefunc
  1274. ; load ESP at free memory hole found
  1275. .loadesp: mov dword [gpt_ptr], esi
  1276. mov dword [gpt_num], ecx
  1277. .loadesp2: mov ecx, dword [esi+40] ;last sector
  1278. mov eax, dword [esi+32] ;first sector
  1279. mov edx, dword [esi+36]
  1280. or edx, edx
  1281. jnz .nextgpt
  1282. or ecx, ecx
  1283. jz .nextgpt
  1284. or eax, eax
  1285. jz .nextgpt
  1286. mov dword [bpb_sec], eax
  1287. ;load BPB
  1288. mov edi, dword [bootboot.initrd_ptr]
  1289. mov word [lbapacket.count], 8
  1290. prot_readsector
  1291. ;parse fat on EFI System Partition
  1292. @@: cmp dword [edi + bpb.fst2], 'FAT3'
  1293. je .isfat
  1294. cmp dword [edi + bpb.fst], 'FAT1'
  1295. je .isfat
  1296. ;no, then it's an initrd on the entire partition
  1297. or eax, eax
  1298. jz .nopart
  1299. or ecx, ecx
  1300. jz .nopart
  1301. sub ecx, eax
  1302. shl ecx, 9
  1303. mov dword [bootboot.initrd_size], ecx
  1304. ; load INITRD from partition
  1305. dec ecx
  1306. shr ecx, 12
  1307. mov edi, dword [bootboot.initrd_ptr]
  1308. @@: add edi, 4096
  1309. prot_readsector
  1310. add eax, 8
  1311. dec ecx
  1312. jnz @b
  1313. jmp .initrdloaded
  1314. .isfat: cmp word [edi + bpb.bps], 512
  1315. jne .nextgpt
  1316. ;calculations
  1317. xor eax, eax
  1318. xor ebx, ebx
  1319. xor ecx, ecx
  1320. xor edx, edx
  1321. mov bx, word [edi + bpb.spf16]
  1322. or bx, bx
  1323. jnz @f
  1324. mov ebx, dword [edi + bpb.spf32]
  1325. @@: mov al, byte [edi + bpb.nf]
  1326. mov cx, word [edi + bpb.rsc]
  1327. ;data_sec = numFat*secPerFat
  1328. mul ebx
  1329. ;data_sec += reservedSec
  1330. add eax, ecx
  1331. ;data_sec += ESPsec
  1332. add eax, dword [bpb_sec]
  1333. mov dword [data_sec], eax
  1334. mov dword [root_sec], eax
  1335. xor eax, eax
  1336. mov al, byte [edi + bpb.spc]
  1337. mov dword [clu_sec], eax
  1338. ;FAT16
  1339. ;data_sec += (numRootEnt*32+511)/512
  1340. cmp word [edi + bpb.spf16], 0
  1341. je .fat32bpb
  1342. cmp byte [edi + bpb.fst + 4], '6'
  1343. jne .nextgpt
  1344. xor eax, eax
  1345. mov ax, word [edi + bpb.nr]
  1346. shl eax, 5
  1347. add eax, 511
  1348. shr eax, 9
  1349. add dword [data_sec], eax
  1350. mov byte [fattype], 0
  1351. xor ecx, ecx
  1352. mov cx, word [edi + bpb.spf16]
  1353. jmp .loadfat
  1354. .fat32bpb: ;FAT32
  1355. ;root_sec += (rootCluster-2)*secPerCluster
  1356. mov eax, dword [edi + bpb.rc]
  1357. sub eax, 2
  1358. xor edx, edx
  1359. mov ebx, dword [clu_sec]
  1360. mul ebx
  1361. add dword [root_sec], eax
  1362. mov byte [fattype], 1
  1363. mov ecx, dword [edi + bpb.spf32]
  1364. ;load FAT
  1365. .loadfat: xor eax, eax
  1366. mov ax, word [edi+bpb.rsc]
  1367. add eax, dword [bpb_sec]
  1368. shr ecx, 3
  1369. inc ecx
  1370. mov edi, 0x10000
  1371. mov word [lbapacket.count], 8
  1372. @@: prot_readsector
  1373. add edi, 4096
  1374. add eax, 8
  1375. dec ecx
  1376. jnz @b
  1377. mov ax, word [clu_sec]
  1378. mov word [lbapacket.count], ax
  1379. ;load root directory
  1380. mov eax, dword [root_sec]
  1381. mov edi, dword [bootboot.initrd_ptr]
  1382. prot_readsector
  1383. ;look for BOOTBOOT directory
  1384. mov esi, edi
  1385. mov eax, 'BOOT'
  1386. mov ecx, 255
  1387. .nextroot: cmp dword [esi], eax
  1388. jne @f
  1389. cmp dword [esi+4], eax
  1390. jne @f
  1391. cmp word [esi+8], ' '
  1392. je .foundroot
  1393. @@: add esi, 32
  1394. cmp byte [esi], 0
  1395. jz .nextgpt
  1396. dec ecx
  1397. jnz .nextroot
  1398. jmp .nextgpt
  1399. .foundroot: xor eax, eax
  1400. cmp byte [fattype], 0
  1401. jz @f
  1402. mov ax, word [esi + fatdir.ch]
  1403. shl eax, 16
  1404. @@: mov ax, word [esi + fatdir.cl]
  1405. ;sec = (cluster-2)*secPerCluster+data_sec
  1406. sub eax, 2
  1407. mov ebx, dword [clu_sec]
  1408. mul ebx
  1409. add eax, dword [data_sec]
  1410. mov edi, dword [bootboot.initrd_ptr]
  1411. prot_readsector
  1412. ;look for CONFIG and INITRD
  1413. mov esi, edi
  1414. mov ecx, 255
  1415. mov edx, dword [bkp]
  1416. .nextdir: cmp dword [esi], 'CONF'
  1417. jne .notcfg
  1418. cmp dword [esi+4], 'IG '
  1419. jne .notcfg
  1420. cmp dword [esi+7], ' '
  1421. jne .notcfg
  1422. ; load environment from FS0:/BOOTBOOT/CONFIG
  1423. push edx
  1424. push esi
  1425. push edi
  1426. push ecx
  1427. mov ecx, dword [esi + fatdir.size]
  1428. cmp ecx, 4095
  1429. jbe @f
  1430. mov ecx, 4095
  1431. @@: mov dword [core_len], ecx
  1432. xor eax, eax
  1433. cmp byte [fattype], 0
  1434. jz @f
  1435. mov ax, word [esi + fatdir.ch]
  1436. shl eax, 16
  1437. @@: mov ax, word [esi + fatdir.cl]
  1438. mov edi, 9000h
  1439. .nextcfg: push eax
  1440. ;sec = (cluster-2)*secPerCluster+data_sec
  1441. sub eax, 2
  1442. mov ebx, dword [clu_sec]
  1443. mov word [lbapacket.count], bx
  1444. mul ebx
  1445. shl ebx, 9
  1446. add eax, dword [data_sec]
  1447. push ebx
  1448. prot_readsector
  1449. pop ebx
  1450. pop eax
  1451. add edi, ebx
  1452. sub ecx, ebx
  1453. js .cfgloaded
  1454. jz .cfgloaded
  1455. ;get next cluster from FAT
  1456. cmp byte [fattype], 0
  1457. jz @f
  1458. shl eax, 2
  1459. add eax, 0x10000
  1460. mov eax, dword [eax]
  1461. jmp .nextcfg
  1462. @@: shl eax, 1
  1463. add eax, 0x10000
  1464. mov ax, word [eax]
  1465. and eax, 0FFFFh
  1466. jmp .nextcfg
  1467. .cfgloaded: pop ecx
  1468. pop edi
  1469. pop esi
  1470. pop edx
  1471. xor eax, eax
  1472. mov ecx, 4096
  1473. sub ecx, dword [core_len]
  1474. mov edi, 9000h
  1475. add edi, dword [core_len]
  1476. repnz stosb
  1477. mov dword [core_len], eax
  1478. mov byte [9FFFh], al
  1479. jmp .notinit
  1480. .notcfg:
  1481. cmp dword [esi], 'X86_'
  1482. jne @f
  1483. cmp dword [esi+4], '64 '
  1484. je .altinitrd
  1485. @@: cmp dword [esi], 'INIT'
  1486. jne .notinit
  1487. cmp dword [esi+4], 'RD '
  1488. jne .notinit
  1489. cmp dword [esi+7], edx
  1490. jne .notinit
  1491. .altinitrd: mov ecx, dword [esi + fatdir.size]
  1492. mov dword [bootboot.initrd_size], ecx
  1493. xor eax, eax
  1494. cmp byte [fattype], 0
  1495. jz @f
  1496. mov ax, word [esi + fatdir.ch]
  1497. shl eax, 16
  1498. @@: mov ax, word [esi + fatdir.cl]
  1499. jmp .loadinitrd
  1500. .notinit: add esi, 32
  1501. cmp byte [esi], 0
  1502. jz .loadinitrd
  1503. dec ecx
  1504. jnz .nextdir
  1505. .noinitrd: mov esi, nord
  1506. jmp prot_diefunc
  1507. ;load cluster chain, eax=cluster, ecx=size
  1508. .loadinitrd:
  1509. mov edi, dword [bootboot.initrd_ptr]
  1510. .nextclu: push eax
  1511. ;sec = (cluster-2)*secPerCluster+data_sec
  1512. sub eax, 2
  1513. mov ebx, dword [clu_sec]
  1514. mov word [lbapacket.count], bx
  1515. mul ebx
  1516. shl ebx, 9
  1517. add eax, dword [data_sec]
  1518. push ebx
  1519. prot_readsector
  1520. pop ebx
  1521. pop eax
  1522. add edi, ebx
  1523. sub ecx, ebx
  1524. js .initrdloaded
  1525. jz .initrdloaded
  1526. ;get next cluster from FAT
  1527. cmp byte [fattype], 0
  1528. jz @f
  1529. shl eax, 2
  1530. add eax, 0x10000
  1531. mov eax, dword [eax]
  1532. jmp .nextclu
  1533. @@: shl eax, 1
  1534. add eax, 0x10000
  1535. mov ax, word [eax]
  1536. and eax, 0FFFFh
  1537. jmp .nextclu
  1538. .initrdloaded:
  1539. DBG32 dbg_initrd
  1540. mov esi, dword [bootboot.initrd_ptr]
  1541. .initrdrom:
  1542. mov edi, dword [bootboot.initrd_ptr]
  1543. cmp word [esi], 08b1fh
  1544. jne .noinflate
  1545. DBG32 dbg_gzinitrd
  1546. mov ebx, esi
  1547. mov eax, dword [bootboot.initrd_size]
  1548. add ebx, eax
  1549. sub ebx, 4
  1550. mov ecx, dword [ebx]
  1551. mov dword [bootboot.initrd_size], ecx
  1552. add edi, eax
  1553. add edi, 4095
  1554. shr edi, 12
  1555. shl edi, 12
  1556. add eax, ecx
  1557. cmp eax, (INITRD_MAXSIZE+2)*1024*1024
  1558. jb @f
  1559. mov esi, nogzmem
  1560. jmp prot_diefunc
  1561. @@: mov dword [bootboot.initrd_ptr], edi
  1562. ; inflate initrd
  1563. xor eax, eax
  1564. add esi, 2
  1565. lodsb
  1566. cmp al, 8
  1567. jne tinf_err
  1568. lodsb
  1569. mov bl, al
  1570. add esi, 6
  1571. test bl, 4
  1572. jz @f
  1573. lodsw
  1574. add esi, eax
  1575. @@: test bl, 8
  1576. jz .noname
  1577. @@: lodsb
  1578. or al, al
  1579. jnz @b
  1580. .noname: test bl, 16
  1581. jz .nocmt
  1582. @@: lodsb
  1583. or al, al
  1584. jnz @b
  1585. .nocmt: test bl, 2
  1586. jz @f
  1587. add esi, 2
  1588. @@: call tinf_uncompress
  1589. .noinflate:
  1590. ;round up to page size
  1591. mov eax, dword [bootboot.initrd_size]
  1592. add eax, 4095
  1593. shr eax, 12
  1594. shl eax, 12
  1595. mov dword [bootboot.initrd_size], eax
  1596. ;do we have an environment configuration?
  1597. mov ebx, 9000h
  1598. cmp byte [ebx], 0
  1599. jnz .parsecfg
  1600. ;-----load /sys/config------
  1601. mov edx, fsdrivers
  1602. .nextfs1: xor ebx, ebx
  1603. mov bx, word [edx]
  1604. or bx, bx
  1605. jz .errfs1
  1606. mov esi, dword [bootboot.initrd_ptr]
  1607. mov ecx, dword [bootboot.initrd_size]
  1608. add ecx, esi
  1609. mov edi, cfgfile
  1610. push edx
  1611. call ebx
  1612. pop edx
  1613. or ecx, ecx
  1614. jnz .fscfg
  1615. add edx, 2
  1616. jmp .nextfs1
  1617. .fscfg: mov edi, 9000h
  1618. add ecx, 3
  1619. shr ecx, 2
  1620. repnz movsd
  1621. .errfs1:
  1622. ;do we have an environment configuration?
  1623. mov ebx, 9000h
  1624. cmp byte [ebx], 0
  1625. jz .noconf
  1626. ;parse
  1627. .parsecfg: push ebx
  1628. DBG32 dbg_env
  1629. pop esi
  1630. jmp .getnext
  1631. ;skip comments
  1632. .nextvar: cmp byte[esi], '#'
  1633. je .skipcom
  1634. cmp word[esi], '//'
  1635. jne @f
  1636. add esi, 2
  1637. .skipcom: lodsb
  1638. cmp al, 10
  1639. je .getnext
  1640. cmp al, 13
  1641. je .getnext
  1642. or al, al
  1643. jz .parseend
  1644. cmp esi, 0A000h
  1645. ja .parseend
  1646. jmp .skipcom
  1647. @@: cmp word[esi], '/*'
  1648. jne @f
  1649. .skipcom2: inc esi
  1650. cmp word [esi-2], '*/'
  1651. je .getnext
  1652. cmp byte [esi], 0
  1653. jz .parseend
  1654. cmp esi, 0A000h
  1655. ja .parseend
  1656. jmp .skipcom2
  1657. ;only match on beginning of line
  1658. @@: cmp esi, 9000h
  1659. je @f
  1660. cmp byte [esi-1], ' '
  1661. je @f
  1662. cmp byte [esi-1], 13
  1663. jae .next
  1664. ;parse screen dimensions
  1665. @@: cmp dword[esi], 'scre'
  1666. jne @f
  1667. cmp word[esi+4], 'en'
  1668. jne @f
  1669. cmp byte[esi+6], '='
  1670. jne @f
  1671. add esi, 7
  1672. call prot_dec2bin
  1673. mov dword [reqwidth], eax
  1674. inc esi
  1675. call prot_dec2bin
  1676. mov dword [reqheight], eax
  1677. jmp .getnext
  1678. ;get kernel's filename
  1679. @@: cmp dword[esi], 'kern'
  1680. jne @f
  1681. cmp word[esi+4], 'el'
  1682. jne @f
  1683. cmp byte[esi+6], '='
  1684. jne @f
  1685. add esi, 7
  1686. mov edi, kernel
  1687. .copy: lodsb
  1688. or al, al
  1689. jz .copyend
  1690. cmp al, ' '
  1691. jz .copyend
  1692. cmp al, 13
  1693. jbe .copyend
  1694. cmp esi, 0A000h
  1695. ja .copyend
  1696. cmp edi, loader_end-1
  1697. jae .copyend
  1698. stosb
  1699. jmp .copy
  1700. .copyend: xor al, al
  1701. stosb
  1702. jmp .getnext
  1703. @@: cmp dword[esi], 'nosm'
  1704. jne .next
  1705. cmp word[esi+4], 'p='
  1706. jne .next
  1707. cmp byte[esi+6], '1'
  1708. jne .next
  1709. mov byte[nosmp], 1
  1710. .next: inc esi
  1711. ;failsafe
  1712. .getnext: cmp esi, 0A000h
  1713. jae .parseend
  1714. cmp byte [esi], 0
  1715. je .parseend
  1716. ;skip white spaces
  1717. cmp byte [esi], ' '
  1718. je @b
  1719. cmp byte [esi], 13
  1720. jbe @b
  1721. jmp .nextvar
  1722. .noconf: mov edi, ebx
  1723. mov ecx, 1024
  1724. xor eax, eax
  1725. repnz stosd
  1726. mov dword [ebx+0], '// N'
  1727. mov dword [ebx+4], '/A' or (10 shl 16)
  1728. .parseend:
  1729. ;-----load /sys/core------
  1730. mov edx, fsdrivers
  1731. .nextfs: xor ebx, ebx
  1732. mov bx, word [edx]
  1733. or bx, bx
  1734. jz .errfs
  1735. mov esi, dword [bootboot.initrd_ptr]
  1736. mov ecx, dword [bootboot.initrd_size]
  1737. add ecx, esi
  1738. mov edi, kernel
  1739. push edx
  1740. call ebx
  1741. pop edx
  1742. or ecx, ecx
  1743. jnz .coreok
  1744. add edx, 2
  1745. jmp .nextfs
  1746. .errfs2: mov esi, nocore
  1747. jmp prot_diefunc
  1748. .errfs: ; if all drivers failed, search for the first elf executable
  1749. DBG32 dbg_scan
  1750. mov esi, dword [bootboot.initrd_ptr]
  1751. mov ecx, dword [bootboot.initrd_size]
  1752. add ecx, esi
  1753. dec esi
  1754. @@: inc esi
  1755. cmp esi, ecx
  1756. jae .errfs2
  1757. cmp dword [esi], 5A2F534Fh ; OS/Z magic
  1758. je .alt
  1759. cmp dword [esi], 464C457Fh ; ELF magic
  1760. je .alt
  1761. cmp word [esi], 5A4Dh ; MZ magic
  1762. jne @b
  1763. mov eax, dword [esi+0x3c]
  1764. cmp eax, 65536
  1765. jnl @b
  1766. add eax, esi
  1767. cmp dword [eax], 00004550h ; PE magic
  1768. jne @b
  1769. cmp word [eax+4], 8664h ; x86_64
  1770. jne @b
  1771. cmp word [eax+20], 20Bh
  1772. jne @b
  1773. .alt: cmp word [esi+4], 0102h ;lsb 64 bit
  1774. jne @b
  1775. cmp word [esi+18], 62 ;x86_64
  1776. jne @b
  1777. cmp word [esi+0x38], 0 ;e_phnum > 0
  1778. jz @b
  1779. .coreok:
  1780. ; parse PE
  1781. cmp word [esi], 5A4Dh ; MZ magic
  1782. jne .tryelf
  1783. mov ebx, esi
  1784. cmp dword [esi+0x3c], 65536
  1785. jnl .badcore
  1786. add esi, dword [esi+0x3c]
  1787. cmp dword [esi], 00004550h ; PE magic
  1788. jne .badcore
  1789. cmp word [esi+4], 8664h ; x86_64 architecture
  1790. jne .badcore
  1791. cmp word [esi+20], 20Bh ; PE32+ format
  1792. jne .badcore
  1793. DBG32 dbg_pe
  1794. mov eax, dword [esi+36] ; entry point
  1795. mov dword [entrypoint], eax
  1796. mov dword [entrypoint+4], 0FFFFFFFFh
  1797. mov ecx, eax
  1798. sub ecx, dword [esi+40] ; - code base
  1799. add ecx, dword [esi+24] ; + text size
  1800. add ecx, dword [esi+28] ; + data size
  1801. mov edx, dword [esi+32] ; bss size
  1802. shr eax, 31
  1803. jz .badcore
  1804. jmp .mkcore
  1805. ; parse ELF
  1806. .tryelf: cmp dword [esi], 5A2F534Fh ; OS/Z magic
  1807. je @f
  1808. cmp dword [esi], 464C457Fh ; ELF magic
  1809. jne .badcore
  1810. @@: cmp word [esi+4], 0102h ;lsb 64 bit, little endian
  1811. jne .badcore
  1812. cmp word [esi+18], 62 ;x86_64 architecture
  1813. je @f
  1814. .badcore: mov esi, badcore
  1815. jmp prot_diefunc
  1816. @@:
  1817. DBG32 dbg_elf
  1818. mov ebx, esi
  1819. mov eax, dword [esi+0x18]
  1820. mov dword [entrypoint], eax
  1821. mov eax, dword [esi+0x18+4]
  1822. mov dword [entrypoint+4], eax
  1823. ;parse ELF binary
  1824. mov cx, word [esi+0x38] ; program header entries phnum
  1825. mov eax, dword [esi+0x20] ; program header
  1826. add esi, eax
  1827. sub esi, 56
  1828. inc cx
  1829. .nextph: add esi, 56
  1830. dec cx
  1831. jz .badcore
  1832. cmp word [esi], 1 ; p_type, loadable
  1833. jne .nextph
  1834. cmp word [esi+22], 0FFFFh ; p_vaddr == negative address
  1835. jne .nextph
  1836. ;got it
  1837. add ebx, dword [esi+8] ; + P_offset
  1838. mov ecx, dword [esi+32] ; p_filesz
  1839. ; hack to keep symtab and strtab for shared libraries
  1840. cmp byte [ebx+16], 3
  1841. jne @f
  1842. add ecx, 04000h
  1843. @@: mov edx, dword [esi+40] ; p_memsz
  1844. sub edx, ecx
  1845. ;ebx=ptr to core segment, ecx=segment size, edx=bss size
  1846. .mkcore: or ecx, ecx
  1847. jz .badcore
  1848. mov eax, ecx
  1849. add eax, edx
  1850. cmp eax, 2*1024*1024 - 256*1024 - 2*4096; 2M minus stack for 256 cores minus bootboot and environment
  1851. jl @f
  1852. mov esi, bigcore
  1853. jmp prot_diefunc
  1854. @@: mov edi, dword [bootboot.initrd_ptr]
  1855. add edi, dword [bootboot.initrd_size]
  1856. mov dword [core_ptr], edi
  1857. mov dword [core_len], ecx
  1858. ;copy code from segment after initrd
  1859. mov esi, ebx
  1860. mov ebx, ecx
  1861. and bl, 3
  1862. shr ecx, 2
  1863. repnz movsd
  1864. or bl, bl
  1865. jz @f
  1866. mov cl, bl
  1867. repnz movsb
  1868. ;zero out bss
  1869. @@: or edx, edx
  1870. jz @f
  1871. add dword [core_len], edx
  1872. xor eax, eax
  1873. mov ecx, edx
  1874. and dl, 3
  1875. shr ecx, 2
  1876. repnz stosd
  1877. or dl, dl
  1878. jz @f
  1879. mov cl, dl
  1880. repnz stosb
  1881. ;round up to page size
  1882. @@: mov eax, dword [core_len]
  1883. add eax, 4095
  1884. shr eax, 12
  1885. shl eax, 12
  1886. mov dword [core_len], eax
  1887. ;exclude initrd area and core from free mmap
  1888. mov esi, bootboot.mmap
  1889. mov ebx, dword [bootboot.initrd_ptr]
  1890. mov edx, dword [core_ptr]
  1891. add edx, eax
  1892. mov cx, 248
  1893. ; initrd+core (ebx..edx)
  1894. .nextfree: cmp dword [esi], ebx
  1895. ja .excludeok
  1896. mov eax, dword [esi+8]
  1897. and al, 0F0h
  1898. add eax, dword [esi]
  1899. cmp edx, eax
  1900. ja .notini
  1901. ; +--------------+
  1902. ; #######
  1903. cmp dword [esi], ebx
  1904. jne .splitmem
  1905. ; ptr = initrd_ptr+initrd_size+core_len
  1906. mov dword [esi], edx
  1907. sub edx, ebx
  1908. and dl, 0F0h
  1909. ; size -= initrd_size+core_len
  1910. sub dword [esi+8], edx
  1911. jmp .excludeok
  1912. ; +--+ +----------+
  1913. ; #######
  1914. .splitmem: mov edi, bootboot.magic
  1915. add edi, dword [bootboot.size]
  1916. add dword [bootboot.size], 16
  1917. @@: mov eax, dword [edi-16]
  1918. mov dword [edi], eax
  1919. mov eax, dword [edi-12]
  1920. mov dword [edi+4], eax
  1921. mov eax, dword [edi-8]
  1922. mov dword [edi+8], eax
  1923. mov eax, dword [edi-4]
  1924. mov dword [edi+12], eax
  1925. sub edi, 16
  1926. cmp edi, esi
  1927. ja @b
  1928. mov eax, ebx
  1929. sub eax, dword [esi]
  1930. sub dword [esi+24], eax
  1931. inc al
  1932. mov dword [esi+8], eax
  1933. mov dword [esi+16], edx
  1934. sub edx, ebx
  1935. sub dword [esi+24], edx
  1936. jmp .excludeok
  1937. .notini: add esi, 16
  1938. dec cx
  1939. jnz .nextfree
  1940. .excludeok:
  1941. ; -------- SMP ---------
  1942. ; clear LAPIC address and logical core id list
  1943. mov edi, lapic_ptr
  1944. mov ecx, 512/4+1
  1945. xor eax, eax
  1946. repnz stosd
  1947. ; clear flags
  1948. mov byte [bsp_done], al
  1949. cmp byte [nosmp], al
  1950. jne .nosmp
  1951. ; try ACPI first
  1952. mov esi, dword [bootboot.acpi_ptr]
  1953. or esi, esi
  1954. jz .trymp
  1955. mov edx, 4
  1956. cmp byte [esi], 'X' ; XSDT has 8 bytes pointers, but we can only access 4G
  1957. jne @f
  1958. mov edx, 8
  1959. @@: mov ecx, dword [esi+4]
  1960. add esi, 024h
  1961. sub ecx, 024h
  1962. .nextsdt: mov ebx, dword [esi]
  1963. add esi, edx
  1964. cmp dword [ebx], 'APIC' ; look for MADT
  1965. je .madt
  1966. sub ecx, edx
  1967. or ecx, ecx
  1968. jz .trymp
  1969. jmp .nextsdt
  1970. ; MADT found.
  1971. .madt: mov eax, dword [ebx+24h]
  1972. mov dword [lapic_ptr], eax ; madt.lapic_address
  1973. mov ecx, dword [ebx+4]
  1974. add ecx, ebx
  1975. add ebx, 2ch
  1976. mov edi, lapic_ids
  1977. .nextmadtentry:
  1978. cmp word [bootboot.numcores], 255
  1979. jae .acpidone
  1980. cmp byte [ebx], 0 ; madt_entry.type: is it a Local APIC Processor?
  1981. jne @f
  1982. mov al, byte [ebx+4] ; madt_entry.lapicproc.flag & ENABLED
  1983. and al, 1
  1984. jz .badmadt
  1985. xor ax, ax
  1986. mov al, byte [ebx+3] ; madt_entry.lapicproc.lapicid
  1987. cmp al, 0FFh
  1988. je .badmadt
  1989. stosw ; ACPI table holds 1 byte id, but internally we have 2 bytes
  1990. inc word [bootboot.numcores]
  1991. jmp @f
  1992. .badmadt: mov byte [bad_madt], 1
  1993. @@: xor eax, eax
  1994. mov al, byte [ebx+1] ; madt_entry.size
  1995. or al, al
  1996. jz .acpidone
  1997. add ebx, eax
  1998. cmp ebx, ecx
  1999. jae .acpidone
  2000. jmp .nextmadtentry
  2001. .trymp: ; in lack of ACPI, try legacy MP structures
  2002. mov esi, dword [bootboot.mp_ptr]
  2003. or esi, esi
  2004. jz .acpidone
  2005. mov esi, dword [esi+4]
  2006. cmp dword [esi], 'PCMP'
  2007. jne .acpidone
  2008. mov eax, dword [esi+36] ; pcmp.lapic_address
  2009. mov dword [lapic_ptr], eax
  2010. mov cx, word [esi+34] ; pcmp.numentries
  2011. add esi, 44 ; pcmp header length
  2012. mov edi, lapic_ids
  2013. .nextpcmpentry:
  2014. cmp word [bootboot.numcores], 255
  2015. jae .acpidone
  2016. cmp byte [esi], 0 ; pcmp_entry.type: is it a Local APIC Processor?
  2017. jne @f
  2018. xor ax, ax
  2019. mov al, byte [esi+1] ; pcmp_entry.lapicproc.lapicid
  2020. stosw ; PCMP has 1 byte id, but we use 2 bytes internally
  2021. inc word [bootboot.numcores]
  2022. add esi, 12
  2023. @@: add esi, 8
  2024. dec cx
  2025. jnz .nextpcmpentry
  2026. .acpidone:
  2027. ; failsafe
  2028. cmp dword [lapic_ptr], 0
  2029. jz @f
  2030. cmp word [bootboot.numcores], 1
  2031. ja .smpok
  2032. @@: mov word [bootboot.numcores], 1
  2033. mov ax, word [bootboot.bspid]
  2034. mov word [lapic_ids], ax
  2035. mov dword [lapic_ptr], 0
  2036. jmp .stks
  2037. .smpok:
  2038. if BBDEBUG eq 1
  2039. xor eax, eax
  2040. mov dword [gpt_ptr], eax
  2041. mov dword [gpt_num], eax
  2042. prot_realmode
  2043. mov bx, word [bootboot.numcores]
  2044. mov di, gpt_ptr
  2045. mov cx, 100
  2046. mov dx, bx
  2047. cmp bx, cx
  2048. jl @f
  2049. mov ax, bx
  2050. xor dx, dx
  2051. div cx
  2052. add al, '0'
  2053. stosb
  2054. @@: mov cx, 10
  2055. mov ax, dx
  2056. xor dx, dx
  2057. div cx
  2058. cmp bx, cx
  2059. jl @f
  2060. add al, '0'
  2061. stosb
  2062. @@: mov al, dl
  2063. add al, '0'
  2064. stosb
  2065. xor al, al
  2066. stosb
  2067. mov si, dbg_smp
  2068. call real_printfunc
  2069. mov si, gpt_ptr
  2070. call real_printfunc
  2071. cmp byte [bad_madt], 0
  2072. jz @f
  2073. mov si, dbg_madt
  2074. call real_printfunc
  2075. @@: mov si, crlf
  2076. call real_printfunc
  2077. real_protmode
  2078. end if
  2079. .stks: ; remove core stacks from memory map
  2080. xor eax, eax
  2081. mov ax, word [bootboot.numcores]
  2082. shl eax, 10
  2083. add eax, 0FFFh ; round up to page size
  2084. and ax, 0F000h
  2085. mov edi, bootboot.mmap
  2086. add dword [edi], eax
  2087. sub dword [edi+8], eax
  2088. ; ------- set video resolution -------
  2089. prot_realmode
  2090. DBG dbg_vesa
  2091. xor ax, ax
  2092. mov es, ax
  2093. ;get VESA VBE2.0 info
  2094. mov ax, 4f00h
  2095. mov di, 0A000h
  2096. mov dword [di], 'VBE2'
  2097. ;this call requires a big stack
  2098. push ds
  2099. push es
  2100. int 10h
  2101. pop es
  2102. pop ds
  2103. cmp ax, 004fh
  2104. je @f
  2105. .viderr: mov si, novbe
  2106. jmp real_diefunc
  2107. ;read dword pointer and copy string to 1st 64k
  2108. ;available video modes
  2109. @@: xor esi, esi
  2110. xor edi, edi
  2111. mov si, word [0A000h+0Eh]
  2112. mov ax, word [0A000h+10h]
  2113. mov ds, ax
  2114. xor ax, ax
  2115. mov es, ax
  2116. mov di, 0A000h+400h
  2117. mov cx, 64
  2118. @@: lodsw
  2119. cmp ax, 0ffffh
  2120. je @f
  2121. or ax, ax
  2122. jz @f
  2123. stosw
  2124. dec cx
  2125. jnz @b
  2126. @@: xor ax, ax
  2127. stosw
  2128. ;iterate on modes
  2129. mov si, 0A000h+400h
  2130. .nextmode: mov di, 0A000h+800h
  2131. xor ax, ax
  2132. mov word [0A000h+802h], ax ; vbe mode
  2133. lodsw
  2134. or ax, ax
  2135. jz .viderr
  2136. mov cx, ax
  2137. mov ax, 4f01h
  2138. push bx
  2139. push cx
  2140. push si
  2141. push di
  2142. push ds
  2143. push es
  2144. int 10h
  2145. pop es
  2146. pop ds
  2147. pop di
  2148. pop si
  2149. pop cx
  2150. pop bx
  2151. cmp ax, 004fh
  2152. jne .viderr
  2153. bts cx, 13
  2154. bts cx, 14
  2155. mov ax, word [0A000h+800h] ; vbe flags
  2156. and ax, VBE_MODEFLAGS
  2157. cmp ax, VBE_MODEFLAGS
  2158. jne .nextmode
  2159. ;check memory model (direct)
  2160. cmp byte [0A000h+81bh], 6
  2161. jne .nextmode
  2162. ;check bpp
  2163. cmp byte [0A000h+819h], 32
  2164. jne .nextmode
  2165. ;check min width
  2166. mov ax, word [reqwidth]
  2167. cmp ax, 640
  2168. ja @f
  2169. mov ax, 640
  2170. @@: cmp word [0A000h+812h], ax
  2171. jne .nextmode
  2172. ;check min height
  2173. mov ax, word [reqheight]
  2174. cmp ax, 480
  2175. ja @f
  2176. mov ax, 480
  2177. @@: cmp word [0A000h+814h], ax
  2178. jb .nextmode
  2179. ;match? go no further
  2180. .match: xor edx, edx
  2181. xor ebx, ebx
  2182. xor eax, eax
  2183. mov bx, word [0A000h+810h]
  2184. mov word [bootboot.fb_scanline], bx
  2185. mov ax, word [0A000h+812h]
  2186. mov word [bootboot.fb_width], ax
  2187. mov ax, word [0A000h+814h]
  2188. mov word [bootboot.fb_height], ax
  2189. mul ebx
  2190. mov dword [bootboot.fb_size], eax
  2191. mov eax, dword [0A000h+828h]
  2192. mov dword [bootboot.fb_ptr], eax
  2193. mov byte [bootboot.fb_type],FB_ARGB ; blue offset
  2194. cmp byte [0A000h+824h], 0
  2195. je @f
  2196. mov byte [bootboot.fb_type],FB_RGBA
  2197. cmp byte [0A000h+824h], 8
  2198. je @f
  2199. mov byte [bootboot.fb_type],FB_ABGR
  2200. cmp byte [0A000h+824h], 16
  2201. je @f
  2202. mov byte [bootboot.fb_type],FB_BGRA
  2203. @@: ; set video mode
  2204. mov bx, cx
  2205. bts bx, 14 ;flat linear
  2206. mov ax, 4f02h
  2207. push ds
  2208. push es
  2209. int 10h
  2210. pop es
  2211. pop ds
  2212. cmp ax, 004fh
  2213. jne .viderr
  2214. ;no debug output after this point
  2215. ;inform firmware that we're about to leave it's realm
  2216. mov ax, 0EC00h
  2217. mov bx, 2 ; 64 bit
  2218. int 15h
  2219. real_protmode
  2220. ; -------- paging ---------
  2221. ;map core at higher half of memory
  2222. ;address 0xffffffffffe00000
  2223. xor eax, eax
  2224. mov edi, 0A000h
  2225. mov ecx, (14000h+256*1024-0A000h)/4
  2226. repnz stosd
  2227. ;PML4
  2228. mov edi, 0A000h
  2229. ;pointer to 2M PDPE (first 4G RAM identity mapped)
  2230. mov dword [edi], 0E003h
  2231. ;pointer to 4k PDPE (core mapped at -2M)
  2232. mov dword [edi+4096-8], 0B003h
  2233. ;4K PDPE
  2234. mov edi, 0B000h
  2235. mov dword [edi+4096-8], 0C003h
  2236. ;4K PDE
  2237. mov edi, 0C000h+3840
  2238. mov eax, dword[bootboot.fb_ptr] ;map framebuffer
  2239. mov al,83h
  2240. mov ecx, 31
  2241. @@: stosd
  2242. add edi, 4
  2243. add eax, 2*1024*1024
  2244. dec ecx
  2245. jnz @b
  2246. mov dword [0C000h+4096-8], 0D003h
  2247. ;4K PT
  2248. mov dword[0D000h], 08001h ;map bootboot
  2249. mov dword[0D008h], 09001h ;map configuration
  2250. mov edi, 0D010h
  2251. mov eax, dword[core_ptr] ;map core text segment
  2252. inc eax
  2253. mov ecx, dword[core_len]
  2254. shr ecx, 12
  2255. inc ecx
  2256. @@: stosd
  2257. add edi, 4
  2258. add eax, 4096
  2259. dec ecx
  2260. jnz @b
  2261. ;map core stacks (one page per 4 cores)
  2262. mov edi, 0DFF8h
  2263. mov eax, 014003h
  2264. mov cx, word [bootboot.numcores]
  2265. add cx, 3
  2266. shr cx, 2
  2267. @@: mov dword[edi], eax
  2268. sub edi, 8
  2269. add eax, 1000h
  2270. dec cx
  2271. jnz @b
  2272. ;identity mapping
  2273. ;2M PDPE
  2274. mov edi, 0E000h
  2275. mov dword [edi], 0F003h
  2276. mov dword [edi+8], 010003h
  2277. mov dword [edi+16], 011003h
  2278. mov dword [edi+24], 012003h
  2279. ;2M PDE
  2280. mov edi, 0F000h
  2281. xor eax, eax
  2282. mov al, 83h
  2283. mov ecx, 512* 4;G RAM
  2284. @@: stosd
  2285. add edi, 4
  2286. add eax, 2*1024*1024
  2287. dec ecx
  2288. jnz @b
  2289. ;first 2M mapped by page
  2290. mov dword [0F000h], 013003h
  2291. mov edi, 013000h
  2292. mov eax, 3
  2293. mov ecx, 512
  2294. @@: stosd
  2295. add edi, 4
  2296. add eax, 4096
  2297. dec ecx
  2298. jnz @b
  2299. mov al, 0FFh ;disable PIC
  2300. out 021h, al
  2301. out 0A1h, al
  2302. in al, 70h ;disable NMI
  2303. or al, 80h
  2304. out 70h, al
  2305. ; ------- send INIT IPI and SIPI --------
  2306. cmp word [bootboot.numcores], 2
  2307. jb .nosmp
  2308. cmp dword [lapic_ptr], 0
  2309. jz .nosmp
  2310. ; relocate AP trampoline
  2311. mov esi, ap_trampoline
  2312. mov edi, 7000h
  2313. mov ecx, (ap_start-ap_trampoline+3)/4
  2314. repnz movsd
  2315. ; disable ICMR
  2316. mov al, 070h
  2317. out 22h, al
  2318. in al, 23h
  2319. or al, 1
  2320. out 23h, al
  2321. ; enable Local APIC
  2322. mov esi, dword [lapic_ptr]
  2323. mov al, 1
  2324. shl eax, 24
  2325. mov dword [esi + 0D0h], eax ; logical destination
  2326. xor eax, eax
  2327. sub eax, 1
  2328. mov dword [esi + 0E0h], eax ; destination form
  2329. mov eax, dword [esi + 0F0h] ; spurious + enable
  2330. mov ax, 1FFh
  2331. mov dword [esi + 0F0h], eax
  2332. mov dword [esi + 080h], 0 ; task priority
  2333. ; make sure we use the correct Local APIC ID for the BSP
  2334. mov eax, dword [esi + 020h]
  2335. shr eax, 24
  2336. mov word [bootboot.bspid], ax
  2337. mov ecx, 1Bh ; enable APIC MSR
  2338. rdmsr
  2339. bt eax, 1
  2340. wrmsr
  2341. mov al, 0fh ; CMOS warm reset code 0A
  2342. out 70h, al
  2343. mov al, 0ah
  2344. out 71h, al
  2345. mov dword [467h], 07000000h ; warm reset vector
  2346. ; use broadcast IPI if MADT is okay (no bcast id and all CPUs enabled)
  2347. cmp byte [bad_madt], 0
  2348. jnz .onebyone
  2349. ; send Broadcast INIT IPI
  2350. mov eax, 0C4500h
  2351. mov dword [esi + 300h], eax
  2352. ; wait 10 millisec
  2353. prot_sleep 50
  2354. ; send Broadcast STARTUP IPI
  2355. mov eax, 0C4607h
  2356. mov dword [esi + 300h], eax
  2357. ; wait 200 microsec
  2358. prot_sleep 1
  2359. ; send second STARTUP IPI
  2360. mov eax, 0C4607h
  2361. mov dword [esi + 300h], eax
  2362. ; wait 200 microsec
  2363. prot_sleep 1
  2364. jmp .nosmp
  2365. .onebyone:
  2366. ; send IPIs to specific cores one by one
  2367. xor edx, edx
  2368. .initcore: cmp dx, word [bootboot.numcores]
  2369. jae .sipi
  2370. mov esi, edx
  2371. inc edx
  2372. shl esi, 1
  2373. add esi, lapic_ids
  2374. mov bx, word [esi]
  2375. cmp bx, word [bootboot.bspid]
  2376. je .initcore
  2377. shl ebx, 24
  2378. ; clear APIC error
  2379. mov esi, dword [lapic_ptr]
  2380. mov dword [esi + 280h], 0
  2381. mov eax, dword [esi + 280h]
  2382. add esi, 20h
  2383. ; select AP
  2384. @@: pause
  2385. mov eax, dword [esi + 300h]
  2386. bt eax, 12
  2387. jc @b
  2388. mov eax, dword [esi + 310h]
  2389. and eax, 00ffffffh
  2390. or eax, ebx
  2391. mov dword [esi + 310h], eax
  2392. ; trigger INIT IPI
  2393. mov eax, dword [esi + 300h]
  2394. and eax, 0fff00000h
  2395. or eax, 00C500h
  2396. mov dword [esi + 300h], eax
  2397. ; wait 200 microsec
  2398. prot_sleep 1
  2399. ; select AP
  2400. @@: pause
  2401. mov eax, dword [esi + 300h]
  2402. bt eax, 12
  2403. jc @b
  2404. mov eax, dword [esi + 310h]
  2405. and eax, 00ffffffh
  2406. or eax, ebx
  2407. mov dword [esi + 310h], eax
  2408. ; deassert INIT IPI
  2409. mov eax, dword [esi + 300h]
  2410. and eax, 0fff00000h
  2411. or eax, 008500h
  2412. mov dword [esi + 300h], eax
  2413. jmp .initcore
  2414. .sipi:
  2415. ; wait 10 millisec
  2416. prot_sleep 50
  2417. xor edx, edx
  2418. .nextcore: cmp dx, word [bootboot.numcores]
  2419. jae .nosmp
  2420. mov esi, edx
  2421. inc edx
  2422. shl esi, 1
  2423. add esi, lapic_ids
  2424. mov bx, word [esi]
  2425. cmp bx, word [bootboot.bspid]
  2426. je .nextcore
  2427. shl ebx, 24
  2428. mov word [ap_done], 0
  2429. ; select AP
  2430. mov esi, dword [lapic_ptr]
  2431. @@: pause
  2432. mov eax, dword [esi + 300h]
  2433. bt eax, 12
  2434. jc @b
  2435. mov eax, dword [esi + 310h]
  2436. and eax, 00ffffffh
  2437. or eax, ebx
  2438. mov dword [esi + 310h], eax
  2439. ; send STARTUP IPI
  2440. mov eax, dword [esi + 300h]
  2441. and eax, 0fff0f800h
  2442. or eax, 004607h ; start at 0700:0000h
  2443. mov dword [esi + 300h], eax
  2444. ; wait 10 millisec
  2445. prot_sleep 50
  2446. ; do we need a second SIPI?
  2447. cmp word [ap_done], 0
  2448. jnz .nextcore
  2449. ; select AP
  2450. @@: pause
  2451. mov eax, dword [esi + 300h]
  2452. bt eax, 12
  2453. jc @b
  2454. mov eax, dword [esi + 310h]
  2455. and eax, 00ffffffh
  2456. or eax, ebx
  2457. mov dword [esi + 310h], eax
  2458. ; send STARTUP IPI
  2459. mov eax, dword [esi + 300h]
  2460. and eax, 0fff0f800h
  2461. or eax, 004607h
  2462. mov dword [esi + 300h], eax
  2463. ; wait 10 millisec
  2464. prot_sleep 50
  2465. jmp .nextcore
  2466. .nosmp:
  2467. ;Enter long mode
  2468. cli
  2469. ;release AP spinlock
  2470. lock inc byte [bsp_done]
  2471. ;don't use stack below this line
  2472. longmode_init:
  2473. mov eax, 1101101000b ;Set PAE, MCE, PGE; OSFXSR, OSXMMEXCPT (enable SSE)
  2474. mov cr4, eax
  2475. mov eax, 0A000h
  2476. mov cr3, eax
  2477. mov ecx, 0C0000080h ;EFER MSR
  2478. rdmsr
  2479. or eax, 100h ;enable long mode
  2480. wrmsr
  2481. mov eax, 0C0000011h ;clear EM, MP (enable SSE) and WP
  2482. mov cr0, eax ;enable paging with cache disabled
  2483. lgdt [GDT64_value] ;read 80 bit address
  2484. jmp 8:.bootboot_startcore
  2485. USE64
  2486. .bootboot_startcore:
  2487. xor rax, rax ;load long mode segments
  2488. mov ax, 10h
  2489. mov ds, ax
  2490. mov es, ax
  2491. mov ss, ax
  2492. mov fs, ax
  2493. mov gs, ax
  2494. ; find out our lapic id
  2495. mov eax, dword [lapic_ptr]
  2496. or eax, eax
  2497. jz @f
  2498. mov eax, dword [rax + 020h]
  2499. shr eax, 24
  2500. @@: mov edx, eax
  2501. ; get array index for it
  2502. xor rbx, rbx
  2503. mov rsi, lapic_ids
  2504. mov cx, word [bootboot.numcores]
  2505. @@: lodsw
  2506. cmp ax, dx
  2507. je @f
  2508. inc ebx
  2509. dec cx
  2510. jnz @b
  2511. xor rbx, rbx
  2512. @@: mov rdi, rbx
  2513. shl rbx, 10 ; 1k stack for each core
  2514. ; set stack and call _start() in sys/core
  2515. xor rsp, rsp ;sp = core_num * -1024
  2516. sub rsp, rbx
  2517. jmp qword[entrypoint]
  2518. nop
  2519. nop
  2520. nop
  2521. nop
  2522. USE32
  2523. include "fs.inc"
  2524. include "tinf.inc"
  2525. ;encryption support for FS/Z
  2526. ; --- SHA-256 ---
  2527. sha_init: xor eax, eax
  2528. mov dword [sha_l], eax
  2529. mov dword [sha_b], eax
  2530. mov dword [sha_b+4], eax
  2531. mov dword [sha_s ], 06a09e667h
  2532. mov dword [sha_s+ 4], 0bb67ae85h
  2533. mov dword [sha_s+ 8], 03c6ef372h
  2534. mov dword [sha_s+12], 0a54ff53ah
  2535. mov dword [sha_s+16], 0510e527fh
  2536. mov dword [sha_s+20], 09b05688ch
  2537. mov dword [sha_s+24], 01f83d9abh
  2538. mov dword [sha_s+28], 05be0cd19h
  2539. ret
  2540. ; IN: ebx = buffer, ecx = length
  2541. sha_upd: push esi
  2542. or ecx, ecx
  2543. jz .end
  2544. mov esi, ebx
  2545. mov edi, dword [sha_l]
  2546. add edi, sha_d
  2547. ; for(;len--;d++) {
  2548. ; ctx->d[ctx->l++]=*d;
  2549. .next: movsb
  2550. inc byte [sha_l]
  2551. ; if(ctx->l==64) {
  2552. cmp byte [sha_l], 64
  2553. jne @f
  2554. ; sha256_t(ctx);
  2555. call sha_final.sha_t
  2556. ; SHA_ADD(ctx->b[0],ctx->b[1],512);
  2557. add dword [sha_b], 512
  2558. adc dword [sha_b+4], 0
  2559. ; ctx->l=0;
  2560. mov byte [sha_l], 0
  2561. sub edi, 64
  2562. ; }
  2563. @@: dec ecx
  2564. jnz .next
  2565. .end: pop esi
  2566. ret
  2567. ; IN: edi = output buffer
  2568. sha_final: push esi
  2569. push edi
  2570. mov ebx, edi
  2571. ; i=ctx->l; ctx->d[i++]=0x80;
  2572. mov edi, dword [sha_l]
  2573. mov ecx, edi
  2574. add edi, sha_d
  2575. mov al, 80h
  2576. stosb
  2577. inc ecx
  2578. xor eax, eax
  2579. ; if(ctx->l<56) {while(i<56) ctx->d[i++]=0x00;}
  2580. cmp cl, 57
  2581. jae @f
  2582. neg ecx
  2583. add ecx, 56
  2584. repnz stosb
  2585. jmp .padded
  2586. @@: ; else {while(i<64) ctx->d[i++]=0x00;sha256_t(ctx);memset(ctx->d,0,56);}
  2587. neg ecx
  2588. add ecx, 64
  2589. repnz stosb
  2590. call .sha_t
  2591. mov ecx, 56/4
  2592. mov edi, sha_d
  2593. repnz stosd
  2594. .padded: ; SHA_ADD(ctx->b[0],ctx->b[1],ctx->l*8);
  2595. mov eax, dword [sha_l]
  2596. shl eax, 3
  2597. add dword [sha_b], eax
  2598. adc dword [sha_b+4], 0
  2599. ; ctx->d[63]=ctx->b[0];ctx->d[62]=ctx->b[0]>>8;ctx->d[61]=ctx->b[0]>>16;ctx->d[60]=ctx->b[0]>>24;
  2600. mov eax, dword [sha_b]
  2601. bswap eax
  2602. mov dword [sha_d+60], eax
  2603. ; ctx->d[59]=ctx->b[1];ctx->d[58]=ctx->b[1]>>8;ctx->d[57]=ctx->b[1]>>16;ctx->d[56]=ctx->b[1]>>24;
  2604. mov eax, dword [sha_b+4]
  2605. bswap eax
  2606. mov dword [sha_d+56], eax
  2607. ; sha256_t(ctx);
  2608. call .sha_t
  2609. ; for(i=0;i<4;i++) {
  2610. ; h[i] =(ctx->s[0]>>(24-i*8)); h[i+4] =(ctx->s[1]>>(24-i*8));
  2611. ; h[i+8] =(ctx->s[2]>>(24-i*8)); h[i+12]=(ctx->s[3]>>(24-i*8));
  2612. ; h[i+16]=(ctx->s[4]>>(24-i*8)); h[i+20]=(ctx->s[5]>>(24-i*8));
  2613. ; h[i+24]=(ctx->s[6]>>(24-i*8)); h[i+28]=(ctx->s[7]>>(24-i*8));
  2614. ; }
  2615. mov edi, ebx
  2616. mov esi, sha_s
  2617. mov cl, 8
  2618. @@: lodsd
  2619. bswap eax
  2620. stosd
  2621. dec cl
  2622. jnz @b
  2623. pop edi
  2624. pop esi
  2625. ret
  2626. ; private func, sha transform
  2627. .sha_t: push esi
  2628. push edi
  2629. push edx
  2630. push ecx
  2631. push ebx
  2632. ; for(i=0,j=0;i<16;i++,j+=4) m[i]=(ctx->d[j]<<24)|(ctx->d[j+1]<<16)|(ctx->d[j+2]<<8)|(ctx->d[j+3]);
  2633. mov cl, 16
  2634. mov edi, _m
  2635. mov esi, sha_d
  2636. @@: lodsd
  2637. bswap eax
  2638. stosd
  2639. dec cl
  2640. jnz @b
  2641. ; for(;i<64;i++) m[i]=SHA_SIG1(m[i-2])+m[i-7]+SHA_SIG0(m[i-15])+m[i-16];
  2642. mov cl, 48
  2643. ; SHA_SIG0[m[i-15]) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
  2644. @@: mov eax, dword [edi-15*4]
  2645. mov ebx, eax
  2646. mov edx, eax
  2647. ror eax, 7
  2648. ror ebx, 18
  2649. shr edx, 3
  2650. xor eax, ebx
  2651. xor eax, edx
  2652. ; SHA_SIG1(m[i-2]) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
  2653. mov ebx, dword [edi-2*4]
  2654. mov edx, ebx
  2655. ror ebx, 17
  2656. ror edx, 19
  2657. xor ebx, edx
  2658. rol edx, 19
  2659. shr edx, 10
  2660. xor ebx, edx
  2661. add eax, ebx
  2662. ; m[i-7]
  2663. add eax, dword [edi-7*4]
  2664. ; m[i-16]
  2665. add eax, dword [edi-16*4]
  2666. stosd
  2667. dec cl
  2668. jnz @b
  2669. ; a=ctx->s[0];b=ctx->s[1];c=ctx->s[2];d=ctx->s[3];
  2670. ; e=ctx->s[4];f=ctx->s[5];g=ctx->s[6];h=ctx->s[7];
  2671. xor ecx, ecx
  2672. mov cl, 8
  2673. mov esi, sha_s
  2674. mov edi, _a
  2675. repnz movsd
  2676. ; for(i=0;i<64;i++) {
  2677. mov esi, _m
  2678. @@: ; t1=h+SHA_EP1(e)+SHA_CH(e,f,g)+sha256_k[i]+m[i];
  2679. mov eax, dword [_h]
  2680. mov dword [t1], eax
  2681. ; SHA_EP1(e) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
  2682. mov eax, dword [_e]
  2683. mov ebx, eax
  2684. ror eax, 6
  2685. ror ebx, 11
  2686. xor eax, ebx
  2687. ror ebx, 14 ; 25 = 11+14
  2688. xor eax, ebx
  2689. add dword [t1], eax
  2690. ; SHA_CH(e,f,g) (((x)&(y))^(~(x)&(z)))
  2691. mov eax, dword [_e]
  2692. mov ebx, eax
  2693. not ebx
  2694. and eax, dword [_f]
  2695. and ebx, dword [_g]
  2696. xor eax, ebx
  2697. add dword [t1], eax
  2698. ; sha256_k[i]
  2699. mov eax, dword [sha256_k+4*ecx]
  2700. add dword [t1], eax
  2701. ; m[i]
  2702. lodsd
  2703. add dword [t1], eax
  2704. ; t2=SHA_EP0(a)+SHA_MAJ(a,b,c);
  2705. ; SHA_EP0(a) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
  2706. mov eax, dword [_a]
  2707. mov ebx, eax
  2708. ror eax, 2
  2709. ror ebx, 13
  2710. xor eax, ebx
  2711. ror ebx, 9 ; 22 = 13+9
  2712. xor eax, ebx
  2713. mov dword [t2], eax
  2714. ; SHA_MAJ(a,b,c) (((x)&(y))^((x)&(z))^((y)&(z)))
  2715. mov eax, dword [_a]
  2716. mov edx, dword [_c]
  2717. mov ebx, eax
  2718. and eax, dword [_b]
  2719. and ebx, edx
  2720. xor eax, ebx
  2721. mov ebx, dword [_b]
  2722. and ebx, edx
  2723. xor eax, ebx
  2724. add dword [t2], eax
  2725. ; h=g;g=f;f=e;e=d+t1;d=c;c=b;b=a;a=t1+t2;
  2726. mov eax, dword [_g]
  2727. mov dword [_h], eax
  2728. mov eax, dword [_f]
  2729. mov dword [_g], eax
  2730. mov eax, dword [_e]
  2731. mov dword [_f], eax
  2732. mov eax, dword [_d]
  2733. add eax, dword [t1]
  2734. mov dword [_e], eax
  2735. mov eax, dword [_c]
  2736. mov dword [_d], eax
  2737. mov eax, dword [_b]
  2738. mov dword [_c], eax
  2739. mov eax, dword [_a]
  2740. mov dword [_b], eax
  2741. mov eax, dword [t1]
  2742. add eax, dword [t2]
  2743. mov dword [_a], eax
  2744. ; }
  2745. inc cl
  2746. cmp cl, 64
  2747. jne @b
  2748. ; ctx->s[0]+=a;ctx->s[1]+=b;ctx->s[2]+=c;ctx->s[3]+=d;
  2749. ; ctx->s[4]+=e;ctx->s[5]+=f;ctx->s[6]+=g;ctx->s[7]+=h;
  2750. mov cl, 8
  2751. mov esi, _a
  2752. mov edi, sha_s
  2753. @@: lodsd
  2754. add dword [edi], eax
  2755. add edi, 4
  2756. dec cl
  2757. jnz @b
  2758. pop ebx
  2759. pop ecx
  2760. pop edx
  2761. pop edi
  2762. pop esi
  2763. xor eax, eax
  2764. ret
  2765. ; --- CRC-32c ---
  2766. ; IN: esi = buffer, ecx = length
  2767. ; OUT: edx = crc
  2768. crc32_calc: xor edx, edx
  2769. xor eax, eax
  2770. xor ebx, ebx
  2771. or cx, cx
  2772. jz .end
  2773. .next: lodsb
  2774. mov bl, dl
  2775. xor bl, al
  2776. mov eax, edx
  2777. shr edx, 8
  2778. xor edx, dword [crclkp+4*ebx]
  2779. dec cx
  2780. jnz .next
  2781. .end: ret
  2782. ;*********************************************************************
  2783. ;* Data *
  2784. ;*********************************************************************
  2785. ;global descriptor table
  2786. align 16
  2787. GDT_table: dd 0, 0 ;null descriptor
  2788. DATA_PROT = $-GDT_table
  2789. dd 0000FFFFh,00CF9200h ;flat ds
  2790. DATA_BOOT = $-GDT_table
  2791. dd 0000FFFFh,00009200h ;16 bit legacy real mode ds
  2792. CODE_BOOT = $-GDT_table
  2793. dd 0000FFFFh,00009800h ;16 bit legacy real mode cs
  2794. CODE_PROT = $-GDT_table
  2795. dd 0000FFFFh,00CF9A00h ;32 bit prot mode ring0 cs
  2796. dd 00000068h,00CF8900h ;32 bit TSS, not used but required
  2797. GDT_value: dw $-GDT_table-1
  2798. dd GDT_table
  2799. dd 0,0
  2800. align 16
  2801. GDT64_table:dd 0, 0 ;null descriptor
  2802. dd 0000FFFFh,00209800h ;supervisor mode (ring 0) cs
  2803. dd 0000FFFFh,00809200h ;flat data segment
  2804. dd 00000068h,00008900h ;TSS, not used but required by vt-x
  2805. dd 0,0
  2806. GDT64_value:dw $-GDT64_table-1
  2807. dd GDT64_table
  2808. dd 0,0
  2809. ;lookup tables for initrd encryption
  2810. dw 0
  2811. crclkp: dd 000000000h, 0F26B8303h, 0E13B70F7h, 01350F3F4h, 0C79A971Fh, 035F1141Ch, 026A1E7E8h, 0D4CA64EBh
  2812. dd 08AD958CFh, 078B2DBCCh, 06BE22838h, 09989AB3Bh, 04D43CFD0h, 0BF284CD3h, 0AC78BF27h, 05E133C24h
  2813. dd 0105EC76Fh, 0E235446Ch, 0F165B798h, 0030E349Bh, 0D7C45070h, 025AFD373h, 036FF2087h, 0C494A384h
  2814. dd 09A879FA0h, 068EC1CA3h, 07BBCEF57h, 089D76C54h, 05D1D08BFh, 0AF768BBCh, 0BC267848h, 04E4DFB4Bh
  2815. dd 020BD8EDEh, 0D2D60DDDh, 0C186FE29h, 033ED7D2Ah, 0E72719C1h, 0154C9AC2h, 0061C6936h, 0F477EA35h
  2816. dd 0AA64D611h, 0580F5512h, 04B5FA6E6h, 0B93425E5h, 06DFE410Eh, 09F95C20Dh, 08CC531F9h, 07EAEB2FAh
  2817. dd 030E349B1h, 0C288CAB2h, 0D1D83946h, 023B3BA45h, 0F779DEAEh, 005125DADh, 01642AE59h, 0E4292D5Ah
  2818. dd 0BA3A117Eh, 04851927Dh, 05B016189h, 0A96AE28Ah, 07DA08661h, 08FCB0562h, 09C9BF696h, 06EF07595h
  2819. dd 0417B1DBCh, 0B3109EBFh, 0A0406D4Bh, 0522BEE48h, 086E18AA3h, 0748A09A0h, 067DAFA54h, 095B17957h
  2820. dd 0CBA24573h, 039C9C670h, 02A993584h, 0D8F2B687h, 00C38D26Ch, 0FE53516Fh, 0ED03A29Bh, 01F682198h
  2821. dd 05125DAD3h, 0A34E59D0h, 0B01EAA24h, 042752927h, 096BF4DCCh, 064D4CECFh, 077843D3Bh, 085EFBE38h
  2822. dd 0DBFC821Ch, 02997011Fh, 03AC7F2EBh, 0C8AC71E8h, 01C661503h, 0EE0D9600h, 0FD5D65F4h, 00F36E6F7h
  2823. dd 061C69362h, 093AD1061h, 080FDE395h, 072966096h, 0A65C047Dh, 05437877Eh, 04767748Ah, 0B50CF789h
  2824. dd 0EB1FCBADh, 0197448AEh, 00A24BB5Ah, 0F84F3859h, 02C855CB2h, 0DEEEDFB1h, 0CDBE2C45h, 03FD5AF46h
  2825. dd 07198540Dh, 083F3D70Eh, 090A324FAh, 062C8A7F9h, 0B602C312h, 044694011h, 05739B3E5h, 0A55230E6h
  2826. dd 0FB410CC2h, 0092A8FC1h, 01A7A7C35h, 0E811FF36h, 03CDB9BDDh, 0CEB018DEh, 0DDE0EB2Ah, 02F8B6829h
  2827. dd 082F63B78h, 0709DB87Bh, 063CD4B8Fh, 091A6C88Ch, 0456CAC67h, 0B7072F64h, 0A457DC90h, 0563C5F93h
  2828. dd 0082F63B7h, 0FA44E0B4h, 0E9141340h, 01B7F9043h, 0CFB5F4A8h, 03DDE77ABh, 02E8E845Fh, 0DCE5075Ch
  2829. dd 092A8FC17h, 060C37F14h, 073938CE0h, 081F80FE3h, 055326B08h, 0A759E80Bh, 0B4091BFFh, 0466298FCh
  2830. dd 01871A4D8h, 0EA1A27DBh, 0F94AD42Fh, 00B21572Ch, 0DFEB33C7h, 02D80B0C4h, 03ED04330h, 0CCBBC033h
  2831. dd 0A24BB5A6h, 0502036A5h, 04370C551h, 0B11B4652h, 065D122B9h, 097BAA1BAh, 084EA524Eh, 07681D14Dh
  2832. dd 02892ED69h, 0DAF96E6Ah, 0C9A99D9Eh, 03BC21E9Dh, 0EF087A76h, 01D63F975h, 00E330A81h, 0FC588982h
  2833. dd 0B21572C9h, 0407EF1CAh, 0532E023Eh, 0A145813Dh, 0758FE5D6h, 087E466D5h, 094B49521h, 066DF1622h
  2834. dd 038CC2A06h, 0CAA7A905h, 0D9F75AF1h, 02B9CD9F2h, 0FF56BD19h, 00D3D3E1Ah, 01E6DCDEEh, 0EC064EEDh
  2835. dd 0C38D26C4h, 031E6A5C7h, 022B65633h, 0D0DDD530h, 00417B1DBh, 0F67C32D8h, 0E52CC12Ch, 01747422Fh
  2836. dd 049547E0Bh, 0BB3FFD08h, 0A86F0EFCh, 05A048DFFh, 08ECEE914h, 07CA56A17h, 06FF599E3h, 09D9E1AE0h
  2837. dd 0D3D3E1ABh, 021B862A8h, 032E8915Ch, 0C083125Fh, 0144976B4h, 0E622F5B7h, 0F5720643h, 007198540h
  2838. dd 0590AB964h, 0AB613A67h, 0B831C993h, 04A5A4A90h, 09E902E7Bh, 06CFBAD78h, 07FAB5E8Ch, 08DC0DD8Fh
  2839. dd 0E330A81Ah, 0115B2B19h, 0020BD8EDh, 0F0605BEEh, 024AA3F05h, 0D6C1BC06h, 0C5914FF2h, 037FACCF1h
  2840. dd 069E9F0D5h, 09B8273D6h, 088D28022h, 07AB90321h, 0AE7367CAh, 05C18E4C9h, 04F48173Dh, 0BD23943Eh
  2841. dd 0F36E6F75h, 00105EC76h, 012551F82h, 0E03E9C81h, 034F4F86Ah, 0C69F7B69h, 0D5CF889Dh, 027A40B9Eh
  2842. dd 079B737BAh, 08BDCB4B9h, 0988C474Dh, 06AE7C44Eh, 0BE2DA0A5h, 04C4623A6h, 05F16D052h, 0AD7D5351h
  2843. sha256_k: dd 0428a2f98h, 071374491h, 0b5c0fbcfh, 0e9b5dba5h, 03956c25bh, 059f111f1h, 0923f82a4h, 0ab1c5ed5h
  2844. dd 0d807aa98h, 012835b01h, 0243185beh, 0550c7dc3h, 072be5d74h, 080deb1feh, 09bdc06a7h, 0c19bf174h
  2845. dd 0e49b69c1h, 0efbe4786h, 00fc19dc6h, 0240ca1cch, 02de92c6fh, 04a7484aah, 05cb0a9dch, 076f988dah
  2846. dd 0983e5152h, 0a831c66dh, 0b00327c8h, 0bf597fc7h, 0c6e00bf3h, 0d5a79147h, 006ca6351h, 014292967h
  2847. dd 027b70a85h, 02e1b2138h, 04d2c6dfch, 053380d13h, 0650a7354h, 0766a0abbh, 081c2c92eh, 092722c85h
  2848. dd 0a2bfe8a1h, 0a81a664bh, 0c24b8b70h, 0c76c51a3h, 0d192e819h, 0d6990624h, 0f40e3585h, 0106aa070h
  2849. dd 019a4c116h, 01e376c08h, 02748774ch, 034b0bcb5h, 0391c0cb3h, 04ed8aa4ah, 05b9cca4fh, 0682e6ff3h
  2850. dd 0748f82eeh, 078a5636fh, 084c87814h, 08cc70208h, 090befffah, 0a4506cebh, 0bef9a3f7h, 0c67178f2h
  2851. idt16: dw 3FFh
  2852. dq 0
  2853. lbapacket: ;lba packet for BIOS
  2854. .size: dw 10h
  2855. .count: dw 8
  2856. .addr: dd 0A000h
  2857. .sect0: dd 0
  2858. .sect1: dd 0
  2859. spc_packet: db 18h dup 0
  2860. reqwidth: dd 1024
  2861. reqheight: dd 768
  2862. ebdaptr: dd 0
  2863. hw_stack: dd 0
  2864. bpb_sec: dd 0 ;ESP's first sector
  2865. root_sec: dd 0 ;root directory's first sector
  2866. data_sec: dd 0 ;first data sector
  2867. clu_sec: dd 0 ;sector per cluster
  2868. origcount: dw 0
  2869. cdromdev: db 0
  2870. bootdev: db 0
  2871. readdev: db 0
  2872. cntdev: db 0
  2873. hasinitrd: db 0
  2874. hasconfig: db 0
  2875. iscdrom: db 0
  2876. nosmp: db 0
  2877. bad_madt:
  2878. ap_done: dw 0
  2879. bsp_done: db 0 ;flag to indicate APs can run
  2880. fattype: db 0
  2881. bkp: dd ' '
  2882. if BBDEBUG eq 1
  2883. dbg_cpu db " * Detecting CPU",13,10,0
  2884. dbg_A20 db " * Enabling A20",13,10,0
  2885. dbg_mem db " * E820 Memory Map",13,10,0
  2886. dbg_systab db " * System tables",13,10,0
  2887. dbg_time db " * System time",13,10,0
  2888. dbg_serial db " * Initrd over serial",13,10,0
  2889. dbg_gpt db " * Reading GPT",13,10,0
  2890. dbg_cdrom db " * Detected CDROM boot",13,10,0
  2891. dbg_env db " * Environment",13,10,0
  2892. dbg_initrd db " * Initrd loaded",13,10,0
  2893. dbg_gzinitrd db " * Gzip compressed initrd",13,10,0
  2894. dbg_scan db " * Autodetecting kernel",13,10,0
  2895. dbg_elf db " * Parsing ELF64",13,10,0
  2896. dbg_pe db " * Parsing PE32+",13,10,0
  2897. dbg_smp db " * SMP numcores ",0
  2898. dbg_madt db " (bad MADT)",0
  2899. dbg_vesa db " * Screen VESA VBE",13,10,0
  2900. end if
  2901. backup: db " * Backup initrd",13,10,0
  2902. passphrase: db " * Passphrase? ",0
  2903. decrypting: db 13," * Decrypting...",0
  2904. clrdecrypt: db 13," ",13,0
  2905. starting: db "Booting OS..."
  2906. crlf: db 13,10,0
  2907. panic: db "-PANIC: ",0
  2908. noarch: db "Hardware not supported",0
  2909. a20err: db "Failed to enable A20",0
  2910. memerr: db "E820 memory map not found",0
  2911. nogzmem: db "Inflating: "
  2912. noenmem: db "Not enough memory",0
  2913. noacpi: db "ACPI not found",0
  2914. nogpt: db "No GPT found",0
  2915. nopar: db "No boot partition",0
  2916. nord: db "Initrd not found",0
  2917. nolib: db "/sys not found in initrd",0
  2918. nocore: db "Kernel not found in initrd",0
  2919. badcore: db "Kernel is not a valid executable",0
  2920. bigcore: db "Kernel is too big",0
  2921. novbe: db "VESA VBE error, no framebuffer",0
  2922. nogzip: db "Unable to uncompress",0
  2923. notcdsect: db "Not 2048 sector aligned",0
  2924. nocipher: db "Unsupported cipher",13,10,0
  2925. badpass: db 13,"BOOTBOOT-ERROR: Bad passphrase",13,10,0
  2926. cfgfile: db "sys/config",0,0,0
  2927. kernel: db "sys/core"
  2928. db (64-($-kernel)) dup 0
  2929. ;-----------padding to be multiple of 512----------
  2930. db (511-($-loader+511) mod 512) dup 0
  2931. loader_end:
  2932. ;-----------BIOS checksum------------
  2933. chksum = 0
  2934. repeat $-loader
  2935. load b byte from (loader+%-1)
  2936. chksum = (chksum + b) mod 100h
  2937. end repeat
  2938. store byte (100h-chksum) at (loader.checksum)
  2939. ;-----------bss area-----------
  2940. entrypoint: dq ?
  2941. core_ptr: dd ?
  2942. core_len: dd ?
  2943. gpt_ptr: dd ?
  2944. gpt_num: dd ?
  2945. gpt_ent: dd ?
  2946. ncycles: dq ?
  2947. lapic_ptr: dd ?
  2948. lapic_ids:
  2949. tinf_bss_start:
  2950. d_end: dd ?
  2951. d_lzOff: dd ?
  2952. d_dict_ring:dd ?
  2953. d_dict_size:dd ?
  2954. d_dict_idx: dd ?
  2955. d_tag: db ?
  2956. d_bitcount: db ?
  2957. d_bfinal: db ?
  2958. d_curlen: dw ?
  2959. d_ltree:
  2960. d_ltree_table:
  2961. dw 16 dup ?
  2962. d_ltree_trans:
  2963. dw 288 dup ?
  2964. d_dtree:
  2965. d_dtree_table:
  2966. dw 16 dup ?
  2967. d_dtree_trans:
  2968. dw 288 dup ?
  2969. offs: dw 16 dup ?
  2970. num: dw ?
  2971. lengths: db 320 dup ?
  2972. hlit: dw ?
  2973. hdist: dw ?
  2974. hclen: dw ?
  2975. tinf_bss_end:
  2976. virtual at tinf_bss_start
  2977. pass: db 256 dup ?
  2978. sha_d: db 64 dup ?
  2979. sha_l: dd ?
  2980. sha_b: dd 2 dup ?
  2981. sha_s: dd 8 dup ?
  2982. _a: dd ?
  2983. _b: dd ?
  2984. _c: dd ?
  2985. _d: dd ?
  2986. _e: dd ?
  2987. _f: dd ?
  2988. _g: dd ?
  2989. _h: dd ?
  2990. t1: dd ?
  2991. t2: dd ?
  2992. _m: dd 64 dup ?
  2993. chk: db 32 dup ?
  2994. iv: db 32 dup ?
  2995. pl: dd ?
  2996. _i: dd ?
  2997. end virtual
  2998. ;-----------bound check-------------
  2999. ;fasm will generate an error if the code
  3000. ;is bigger than it should be
  3001. db 07C00h-4096-($-loader) dup ?