fs.inc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. ;*
  2. ;* x86_64-bios/fs.inc
  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 Filesystem drivers for initial ramdisk.
  28. ;*
  29. ;*********************************************************************
  30. ;* File System Drivers *
  31. ;*********************************************************************
  32. USE32
  33. fsdrivers:
  34. dw fsz_initrd
  35. dw mfs_initrd
  36. dw cpio_initrd
  37. dw tar_initrd
  38. dw sfs_initrd
  39. dw jamesm_initrd
  40. dw ech_initrd
  41. dw 0
  42. ; ----------- FS/Z ----------
  43. ; Find the kernel on initrd (only supports 4096 logical sector sizes)
  44. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  45. ; OUT: On Success
  46. ; esi: pointer to the first byte, ecx: size in bytes
  47. ; On Error
  48. ; ecx: 0
  49. fsz_initrd:
  50. mov ebx, ecx
  51. xor ecx, ecx
  52. ; FS/Z superblock
  53. cmp dword [esi+512], 'FS/Z' ; FSZ_SuperBlock.magic
  54. jne .nolib
  55. cmp byte [esi+518], 1 ; FSZ_SuperBlock.logsec
  56. jne .nolib
  57. ; encrypted initrd?
  58. cmp dword [esi+520], 0 ; FSZ_SuperBlock.enchash
  59. jz .noenc
  60. mov al, byte [esi+519] ; FSZ_SuperBlock.flags >> 4 (enctype)
  61. and al, 0F0h
  62. jz @f
  63. prot_realmode
  64. real_print loader.name
  65. real_print panic
  66. mov esi, nocipher
  67. call real_printfunc
  68. real_protmode
  69. jmp .err
  70. @@: push edi
  71. prot_realmode
  72. .passagain: real_print passphrase
  73. ; get passphrase from user
  74. mov di, pass
  75. mov byte [di], 0
  76. .getchar: call real_getchar
  77. cmp al, 27 ; Esc
  78. jne @f
  79. real_print clrdecrypt
  80. jmp .err
  81. @@: cmp al, 8 ; Backspace
  82. jne @f
  83. cmp di, pass
  84. je .getchar
  85. mov byte [di], 0
  86. dec di
  87. jmp .getchar
  88. @@: cmp al, 13 ; Enter
  89. je .gotpass
  90. cmp al, 10
  91. je .gotpass
  92. cmp al, ' '
  93. jb .getchar
  94. cmp di, pass+255
  95. jge .getchar
  96. mov word [di], ax
  97. inc di
  98. jmp .getchar
  99. .gotpass: push esi
  100. real_protmode
  101. mov esi, pass
  102. mov ecx, edi
  103. sub ecx, esi
  104. mov dword [pl], ecx
  105. call crc32_calc
  106. prot_realmode
  107. pop esi
  108. cmp dword [esi+520], edx
  109. je .passok
  110. real_print badpass
  111. jmp .passagain
  112. .passok: real_print decrypting
  113. real_protmode
  114. ; decrypt initrd
  115. call sha_init
  116. mov ecx, dword [pl]
  117. mov ebx, pass
  118. call sha_upd
  119. mov ecx, 6
  120. mov ebx, esi
  121. add ebx, 512 ; FSZ_SuperBlock.magic
  122. call sha_upd
  123. mov edi, chk
  124. call sha_final
  125. mov edi, esi
  126. add edi, 680 ; FSZ_SuperBlock.encrypt
  127. mov cl, 32
  128. xor ebx, ebx
  129. @@: mov al, byte [edi]
  130. xor byte [chk+ebx], al
  131. xor eax, eax
  132. stosb
  133. inc ebx
  134. dec cl
  135. jnz @b
  136. stosd
  137. call sha_init
  138. mov ecx, 32
  139. mov ebx, chk
  140. call sha_upd
  141. mov edi, iv
  142. call sha_final
  143. mov eax, dword [esi+528] ; FSZ_SuperBlock.numsec
  144. mov dword [pl], eax
  145. xor eax, eax
  146. inc eax
  147. mov dword [_i], eax ; skip first sector
  148. mov ebx, esi
  149. add ebx, 4096
  150. push esi
  151. .decrypt: mov esi, iv
  152. mov edi, chk
  153. xor ecx, ecx
  154. mov cl, 32/4
  155. repnz movsd
  156. mov cx, 4096
  157. .nextblk: mov al, bl
  158. and al, 31
  159. jnz @f
  160. push ebx
  161. push ecx
  162. call sha_init
  163. mov ecx, 32
  164. mov ebx, chk
  165. call sha_upd
  166. mov ecx, 4
  167. mov ebx, _i
  168. call sha_upd
  169. mov edi, chk
  170. call sha_final
  171. pop ecx
  172. pop ebx
  173. mov edx, edi
  174. @@: mov al, byte [edx]
  175. xor byte [ebx], al
  176. mov al, byte [edx+32]
  177. xor byte [ebx], al
  178. inc ebx
  179. inc edx
  180. dec cx
  181. jnz .nextblk
  182. inc dword [_i]
  183. mov eax, dword [_i]
  184. cmp eax, dword [pl]
  185. jne .decrypt
  186. mov esi, dword [esp]
  187. mov edi, esi
  188. add edi, 680 ; FSZ_SuperBlock.encrypt
  189. mov cl, 8
  190. xor eax, eax
  191. mov dword[esi+520], eax
  192. repnz stosd
  193. add esi, 512
  194. mov ecx, 508
  195. call crc32_calc
  196. pop esi
  197. mov dword [esi+1020], edx ; FSZ_SuperBlock.chksum
  198. ; clear console message
  199. prot_realmode
  200. real_print clrdecrypt
  201. real_protmode
  202. pop edi
  203. ; get root dir inode
  204. .noenc: mov dword [_i], 1024
  205. mov al, byte [esi+520] ; FSZ_SuperBlock.flags
  206. bt ax, 0 ; FSZ_SB_BIGINODE?
  207. jnc @f
  208. mov dword [_i], 2048
  209. @@: mov eax, dword [esi+560] ; FSZ_SuperBlock.rootdirfid
  210. shl eax, 12
  211. add esi, eax
  212. cmp dword [esi], 'FSIN'
  213. je @f
  214. .nolib: mov esi, nolib
  215. .err: xor ecx, ecx
  216. ret
  217. .nocore: mov esi, nocore
  218. jmp .err
  219. @@: ; it has inlined data?
  220. .again: mov eax, dword [esi+448] ; FSZ_Inode.sec
  221. add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
  222. cmp dword [esi], 'FSDR'
  223. je .srchdir
  224. ; no, locate the data
  225. mov ecx, dword [esi]
  226. shl eax, 12
  227. mov esi, dword [bootboot.initrd_ptr]
  228. add esi, eax
  229. cmp dword [esi], 'FSDR'
  230. je .srchdir
  231. ; inlined sector directory or list?
  232. shl ecx, 12
  233. mov esi, dword [bootboot.initrd_ptr]
  234. add esi, ecx
  235. cmp dword [esi], 'FSDR'
  236. jne .nolib
  237. .srchdir: ; find sys/
  238. mov ecx, dword [esi+16] ; FSZ_DirEntHeader.numentries
  239. mov eax, dword [edi]
  240. @@: add esi, 128 ; directories than
  241. cmp dword [esi+16], eax
  242. je @f
  243. dec ecx
  244. jnz @b
  245. jmp .nolib
  246. ; found, get it's inode
  247. @@:
  248. mov eax, dword [esi]
  249. shl eax, 12
  250. mov esi, dword [bootboot.initrd_ptr]
  251. add esi, eax
  252. cmp dword [esi], 'FSIN'
  253. jne .nolib
  254. ;this is not bullet proof
  255. add edi, 4
  256. cmp byte [edi+3], '/'
  257. je .again
  258. ; it has inlined data?
  259. mov eax, dword [esi+448] ; FSZ_Inode.sec
  260. add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
  261. cmp dword [esi], 'FSDR'
  262. je .srchcore
  263. ; no, locate the data
  264. mov ecx, dword [esi]
  265. shl eax, 12
  266. mov esi, dword [bootboot.initrd_ptr]
  267. add esi, eax
  268. cmp dword [esi], 'FSDR'
  269. je .srchdir
  270. ; inlined sector directory or list?
  271. shl ecx, 12
  272. mov esi, dword [bootboot.initrd_ptr]
  273. add esi, ecx
  274. cmp dword [esi], 'FSDR'
  275. jne .nolib
  276. .srchcore: ; find filename
  277. mov ecx, dword [esi+16] ; FSZ_DirEntHeader.numentries
  278. ;filename, 8 characters supported
  279. mov eax, dword [edi]
  280. mov edx, dword [edi+4]
  281. @@: add esi, 128
  282. cmp dword [esi+20], edx
  283. jne .not
  284. cmp dword [esi+16], eax
  285. je @f
  286. .not: dec ecx
  287. jnz @b
  288. jmp .nocore
  289. ; found, get it's inode
  290. @@: mov eax, dword [esi]
  291. shl eax, 12
  292. mov esi, dword [bootboot.initrd_ptr]
  293. add esi, eax
  294. cmp dword [esi], 'FSIN'
  295. jne .nocore
  296. ; get data
  297. mov eax, dword [esi+448] ; FSZ_Inode.sec
  298. mov ecx, dword [esi+464] ; FSZ_Inode.size
  299. or eax, eax
  300. jz .nocore
  301. ; inline? (FSZ_Inode.sec == inode)
  302. mov ebx, esi
  303. shr ebx, 12
  304. cmp eax, ebx
  305. jne .notinline
  306. mov bl, byte [esi+488] ; FSZ_Inode.flags
  307. add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
  308. and bl, 01Fh
  309. jnz @f
  310. ret
  311. @@: mov eax, dword[esi]
  312. jmp @f
  313. shl eax, 12
  314. mov esi, dword [bootboot.initrd_ptr]
  315. add esi, eax
  316. ret
  317. .notinline:
  318. mov bl, byte [esi+488] ; FSZ_Inode.flags
  319. mov bh, bl
  320. and bl, 0Fh
  321. shr bh, 4
  322. add bl, bh ; 0 = direct, no seclist, 1 = indirect or seclist
  323. or bl, bl
  324. jz @f
  325. shl eax, 12
  326. mov esi, dword [bootboot.initrd_ptr]
  327. add esi, eax
  328. mov eax, dword [esi] ; first FSZ_SectorList.sec
  329. @@: shl eax, 12
  330. mov esi, dword [bootboot.initrd_ptr]
  331. add esi, eax
  332. ret
  333. ; ----------- Minix3 FS ----------
  334. ; Find the kernel on initrd (must be defragmented)
  335. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  336. ; OUT: On Success
  337. ; esi: pointer to the first byte, ecx: size in bytes
  338. ; On Error
  339. ; ecx: 0
  340. mfs_initrd:
  341. cmp word[esi + 1048], 'ZM'
  342. jne .err
  343. ; *((uint16_t*)(initrd_p + 1052));
  344. xor ebx, ebx
  345. mov bx, word [esi + 1052]
  346. ; (2 + *((uint16_t*)(initrd_p + 1030)) + *((uint16_t*)(initrd_p + 1032))) * bs;
  347. xor edx, edx
  348. xor eax, eax
  349. mov ax, word [esi + 1030]
  350. mov dx, word [esi + 1032]
  351. add eax, edx
  352. add eax, 2
  353. mul ebx
  354. mov dword [.tbl], eax
  355. ; initrd_p + ino_tbl;
  356. add eax, esi
  357. mov dword [.ino], eax
  358. .again: mov ecx, edi
  359. @@: inc ecx
  360. cmp byte [ecx], '/'
  361. je @f
  362. cmp byte [ecx], 0
  363. jnz @b
  364. @@: ; initrd_p + *((uint32_t*)(ino + 24)) * bs;
  365. mov eax, dword [.ino]
  366. mov eax, dword [eax + 24]
  367. xor ebx, ebx
  368. mov bx, word [esi + 1052]
  369. mul ebx
  370. add eax, esi
  371. mov edx, ebx
  372. shr edx, 6
  373. ; if(*((uint32_t*)d) && !memcmp(s, d + 4, e - s) && !d[e - s])
  374. .srchdir: cmp dword [eax], 0
  375. jnz .next
  376. push edi
  377. push eax
  378. add eax, 4
  379. @@: mov bl, byte [eax]
  380. cmp byte [edi], bl
  381. jne .nomatch
  382. inc eax
  383. inc edi
  384. cmp edi, ecx
  385. jne @b
  386. ; initrd_p + ino_tbl + (*((uint32_t*)d) - 1) * 64;
  387. pop eax
  388. pop edi
  389. mov eax, dword [eax]
  390. dec eax
  391. shl eax, 6
  392. add eax, dword [.tbl]
  393. add eax, esi
  394. mov dword [.ino], eax
  395. cmp byte [ecx], 0
  396. jnz @f
  397. ; *((uint32_t*)(ino + 8))
  398. mov ecx, dword [eax + 8]
  399. ; initrd_p + *((uint32_t*)(ino + 24)) * bs;
  400. mov eax, dword [eax + 24]
  401. xor ebx, ebx
  402. mov bx, word [esi + 1052]
  403. mul ebx
  404. add esi, eax
  405. ret
  406. @@: mov edi, ecx
  407. inc edi
  408. jmp .again
  409. .nomatch: pop eax
  410. pop edi
  411. .next: add eax, 64
  412. dec edx
  413. jz .err
  414. cmp byte[eax + 4], 0
  415. jnz .srchdir
  416. .err: xor ecx, ecx
  417. ret
  418. .tbl: dd 0
  419. .ino: dd 0
  420. ; ----------- cpio ----------
  421. ; Find the kernel on initrd
  422. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  423. ; OUT: On Success
  424. ; esi: pointer to the first byte, ecx: size in bytes
  425. ; On Error
  426. ; ecx: 0
  427. cpio_initrd:
  428. ; upper bound
  429. mov ebx, ecx
  430. xor ecx, ecx
  431. ; strlen(kernel)
  432. mov eax, edi
  433. or eax, eax
  434. jz .err
  435. cmp byte [eax], 0
  436. jz .err
  437. xor ecx, ecx
  438. @@: inc ecx
  439. inc eax
  440. cmp byte [eax], 0
  441. jnz @b
  442. mov dword [.ks], ecx
  443. ; while(ptr.magic=='070707' && ptr<limit)
  444. .next: cmp esi, ebx
  445. jae .err
  446. mov eax, '0707'
  447. cmp dword [esi], eax ; cpio magic
  448. jne .err
  449. cmp word [esi+4], ax ; hpodc
  450. je @f
  451. cmp word [esi+4], '01' ; newc
  452. je .newc
  453. cmp word [esi+4], '02' ; crc
  454. je .newc
  455. .err: xor ecx, ecx
  456. ret
  457. @@: mov eax, esi ; filename len
  458. add eax, 8*6+11
  459. mov ecx, 6
  460. call prot_oct2bin
  461. mov dword [.ns], eax
  462. mov eax, esi ; filesize
  463. add eax, 8*6+11+6
  464. mov ecx, 11
  465. call prot_oct2bin
  466. mov dword [.fs], eax
  467. push esi ; name equals?
  468. push edi
  469. add esi, 9*6+2*11
  470. mov ecx, dword [.ks]
  471. cmp word [esi], './'
  472. jne .notcurdir
  473. add esi, 2
  474. sub ecx, 2
  475. .notcurdir: repz cmpsb
  476. pop edi
  477. pop esi
  478. jz @f
  479. add esi, 76 ; no skip this record
  480. add esi, dword [.ns] ; and check the next one
  481. add esi, dword [.fs]
  482. jmp .next
  483. @@: add esi, 76 ; found! esi=data
  484. add esi, dword [.ns]
  485. mov ecx, dword [.fs] ; ecx=size
  486. ret
  487. .newc: mov edx, esi ; filename len
  488. add esi, 8*11+6
  489. mov ecx, 8
  490. call prot_hex2bin
  491. mov dword [.ns], eax
  492. mov esi, edx ; filesize
  493. add esi, 8*6+6
  494. mov ecx, 8
  495. call prot_hex2bin
  496. mov dword [.fs], eax
  497. mov esi, edx
  498. push esi ; name equals?
  499. push edi
  500. add esi, 110
  501. mov ecx, dword [.ks]
  502. cmp word [esi], './'
  503. jne .notcudir
  504. add esi, 2
  505. sub ecx, 2
  506. .notcudir: repz cmpsb
  507. pop edi
  508. pop esi
  509. jz @f
  510. mov eax, 113 ; no skip this record
  511. add eax, dword [.ns] ; and check the next one
  512. and al, 0FCh
  513. add esi, eax
  514. mov eax, dword [.fs]
  515. add eax, 3
  516. and al, 0FCh
  517. add esi, eax
  518. cmp dword [esi], '0707' ; cpio magic
  519. jne .err
  520. jmp .newc
  521. @@: mov eax, 113 ; found! esi=data
  522. add eax, dword [.ns]
  523. and al, 0FCh
  524. add esi, eax
  525. mov ecx, dword [.fs] ; ecx=size
  526. ret
  527. .ks: dd 0
  528. .ns: dd 0
  529. .fs: dd 0
  530. ; ----------- tar ----------
  531. ; Find the kernel on initrd
  532. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  533. ; OUT: On Success
  534. ; esi: pointer to the first byte, ecx: size in bytes
  535. ; On Error
  536. ; ecx: 0
  537. tar_initrd:
  538. ; upper bound
  539. mov ebx, ecx
  540. xor ecx, ecx
  541. ; strlen(kernel)
  542. mov eax, edi
  543. or eax, eax
  544. jz .err
  545. cmp byte [eax], 0
  546. jz .err
  547. xor ecx, ecx
  548. @@: inc ecx
  549. inc eax
  550. cmp byte [eax], 0
  551. jnz @b
  552. mov dword [.ks], ecx
  553. ; while(ptr.magic=='ustar' && ptr<limit)
  554. .next: cmp esi, ebx
  555. jae .err
  556. cmp dword [esi+257], 'usta' ; tar magic
  557. jne .err
  558. cmp byte [esi+261], 'r' ; tar magic
  559. je @f
  560. .err: xor ecx, ecx
  561. ret
  562. @@: mov eax, esi ; filesize
  563. add eax, 07ch
  564. mov ecx, 11
  565. call prot_oct2bin
  566. mov dword [.fs], eax
  567. push esi ; name equals?
  568. push edi
  569. mov ecx, dword [.ks]
  570. cmp word [esi], './'
  571. jne .notcurdir
  572. add esi, 2
  573. sub ecx, 2
  574. .notcurdir: repz cmpsb
  575. pop edi
  576. pop esi
  577. jz @f
  578. add esi, 512 ; no skip this record
  579. mov eax, dword [.fs] ; and check the next one
  580. add eax, 511
  581. shr eax, 9
  582. shl eax, 9
  583. add esi, eax
  584. jmp .next
  585. @@: add esi, 512 ; found! esi=data
  586. mov ecx, dword [.fs] ; ecx=size
  587. ret
  588. .ks: dd 0
  589. .fs: dd 0
  590. ; ----------- SFS ----------
  591. ; Find the kernel on Stupid File System
  592. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  593. ; OUT: On Success
  594. ; esi: pointer to the first byte, ecx: size in bytes
  595. ; On Error
  596. ; ecx: 0
  597. sfs_initrd:
  598. ; check magic
  599. ; 1.0, Brendan's version
  600. mov byte [.ver], 0
  601. cmp word [esi+01ACh], 'SF'
  602. jne @f
  603. cmp byte [esi+01AEh], 'S'
  604. je .ok
  605. ; 1.1, BenLunt's version
  606. @@: cmp word [esi+01A6h], 'SF'
  607. jne .err
  608. cmp byte [esi+01A8h], 'S'
  609. jne .err
  610. inc byte [.ver]
  611. ; upper bound
  612. .ok: mov ebx, ecx
  613. xor ecx, ecx
  614. ; strlen(kernel)
  615. mov eax, edi
  616. or eax, eax
  617. jz .err
  618. cmp byte [eax], 0
  619. jz .err
  620. xor ecx, ecx
  621. @@: inc ecx
  622. inc eax
  623. cmp byte [eax], 0
  624. jnz @b
  625. mov dword [.ks], ecx
  626. ; get block size
  627. xor eax, eax
  628. inc eax
  629. xor ecx, ecx
  630. mov cl, byte [esi+01BCh]
  631. cmp byte [.ver], 0
  632. jz @f
  633. mov cl, byte [esi+01B6h]
  634. @@: add cl, 7
  635. shl eax, cl
  636. mov dword [.bs], ecx
  637. ; get index area, base + totalblocks*blocksize - indexsize
  638. xor edx, edx
  639. mov eax, dword [esi+01B0h] ; total number of blocks
  640. cmp byte [.ver], 0
  641. jz @f
  642. mov eax, dword [esi+01AAh] ; total number of blocks
  643. @@: mul ecx
  644. add eax, esi
  645. mov ebx, eax
  646. mov edx, dword [esi+01A4h] ; size of index area
  647. cmp byte [.ver], 0
  648. jz @f
  649. mov edx, dword [esi+019Eh] ; size of index area
  650. @@: sub eax, edx
  651. mov edx, esi
  652. mov esi, eax
  653. cmp byte [esi], 02h ; got Starting Marker Entry?
  654. jne .err
  655. ; iterate on index until we reach end or Volume Identifier
  656. .nextindex: cmp esi, ebx
  657. jae .err
  658. cmp byte [esi], 01h
  659. je .err
  660. add esi, 64
  661. cmp byte [esi], 12h ; file entry?
  662. jne .nextindex
  663. push esi ; name equals?
  664. push edi
  665. mov ecx, dword [.ks]
  666. add esi, 022h
  667. add esi, dword [.ver]
  668. repz cmpsb
  669. pop edi
  670. pop esi
  671. jnz .nextindex
  672. mov ebx, esi
  673. mov eax, dword [esi+0Ah] ; start_block
  674. cmp byte [.ver], 0
  675. jz @f
  676. mov eax, dword [esi+0Bh] ; start_block
  677. @@: mov esi, edx
  678. xor edx, edx
  679. mov ecx, dword [.bs]
  680. mul ecx ; * blocksize
  681. add esi, eax ; base +
  682. ; found! esi=data, ecx=size
  683. mov ecx, dword [ebx+01Ah] ; file_length
  684. cmp byte [.ver], 0
  685. jz @f
  686. mov ecx, dword [ebx+01Bh] ; file_length
  687. @@: ret
  688. .err: xor ecx, ecx
  689. ret
  690. .ks: dd 0
  691. .bs: dd 0
  692. .ver: dd 0
  693. ; ----------- JamesMolloy's ----------
  694. ; Find the kernel on initrd
  695. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  696. ; OUT: On Success
  697. ; esi: pointer to the first byte, ecx: size in bytes
  698. ; On Error
  699. ; ecx: 0
  700. jamesm_initrd:
  701. ; no real magic, so we assume initrd contains at least one file...
  702. cmp word [esi+2], 0
  703. jne .err
  704. cmp byte [esi+4], 0BFh
  705. jne .err
  706. ; upper bound
  707. xor ecx, ecx
  708. ; strlen(kernel)
  709. mov eax, edi
  710. or eax, eax
  711. jz .err
  712. cmp byte [eax], 0
  713. jz .err
  714. xor ecx, ecx
  715. @@: inc ecx
  716. inc eax
  717. cmp byte [eax], 0
  718. jnz @b
  719. mov dword [.ks], ecx
  720. mov ebx, esi
  721. ; edx=*(int*)initrd_p
  722. lodsd
  723. mov edx, eax
  724. ; for(i=0;i<nf && ptr[0]==0xBF;i++)
  725. @@: lodsb
  726. cmp al, 0BFh
  727. jne .err
  728. push esi ; name equals?
  729. push edi
  730. mov ecx, dword [.ks]
  731. repz cmpsb
  732. pop edi
  733. pop esi
  734. jz @f
  735. add esi, 72
  736. dec dx
  737. jnz @b
  738. .err: xor ecx, ecx
  739. ret
  740. @@: mov ecx, dword [esi+68]
  741. mov esi, dword [esi+64]
  742. add esi, ebx
  743. ret
  744. .ks: dd 0
  745. ; ----------- echfs ----------
  746. ; Find the kernel on initrd
  747. ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
  748. ; OUT: On Success
  749. ; esi: pointer to the first byte, ecx: size in bytes
  750. ; On Error
  751. ; ecx: 0
  752. ech_initrd:
  753. cmp dword [esi + 4], '_ECH'
  754. jne .err
  755. cmp dword [esi + 8], '_FS_'
  756. jne .err
  757. mov edx, esi
  758. mov esi, dword[esi + 12]
  759. shl esi, 3
  760. add esi, 16*512
  761. mov ebx, 0FFFFFFFFh
  762. .again: xor ecx, ecx
  763. @@: inc cx
  764. cmp byte [edi + ecx], 0
  765. jz @f
  766. cmp byte [edi + ecx], '/'
  767. jne @b
  768. @@:
  769. .next: cmp dword [esi], 0
  770. jz .err
  771. cmp dword [esi], ebx
  772. jne .not
  773. cmp byte [esi + ecx + 9], 0
  774. jnz .not
  775. push esi
  776. push edi
  777. push ecx
  778. add esi, 9
  779. rep cmpsb
  780. pop ecx
  781. pop edi
  782. pop esi
  783. jnz .not
  784. mov ebx, dword [esi + 240]
  785. add edi, ecx
  786. inc edi
  787. cmp byte [edi - 1], '/'
  788. je .again
  789. cmp byte [esi + 8], 0
  790. jnz .err
  791. mov ecx, dword [esi + 248]
  792. mov esi, ebx
  793. shl esi, 9
  794. add esi, edx
  795. ret
  796. .not: add esi, 256
  797. jmp .next
  798. .err: xor ecx, ecx
  799. ret