123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- ;*
- ;* x86_64-bios/fs.inc
- ;*
- ;* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
- ;*
- ;* Permission is hereby granted, free of charge, to any person
- ;* obtaining a copy of this software and associated documentation
- ;* files (the "Software"), to deal in the Software without
- ;* restriction, including without limitation the rights to use, copy,
- ;* modify, merge, publish, distribute, sublicense, and/or sell copies
- ;* of the Software, and to permit persons to whom the Software is
- ;* furnished to do so, subject to the following conditions:
- ;*
- ;* The above copyright notice and this permission notice shall be
- ;* included in all copies or substantial portions of the Software.
- ;*
- ;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- ;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- ;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- ;* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- ;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- ;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- ;* DEALINGS IN THE SOFTWARE.
- ;*
- ;* This file is part of the BOOTBOOT Protocol package.
- ;* @brief Filesystem drivers for initial ramdisk.
- ;*
- ;*********************************************************************
- ;* File System Drivers *
- ;*********************************************************************
- USE32
- fsdrivers:
- dw fsz_initrd
- dw mfs_initrd
- dw cpio_initrd
- dw tar_initrd
- dw sfs_initrd
- dw jamesm_initrd
- dw ech_initrd
- dw 0
- ; ----------- FS/Z ----------
- ; Find the kernel on initrd (only supports 4096 logical sector sizes)
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- fsz_initrd:
- mov ebx, ecx
- xor ecx, ecx
- ; FS/Z superblock
- cmp dword [esi+512], 'FS/Z' ; FSZ_SuperBlock.magic
- jne .nolib
- cmp byte [esi+518], 1 ; FSZ_SuperBlock.logsec
- jne .nolib
- ; encrypted initrd?
- cmp dword [esi+520], 0 ; FSZ_SuperBlock.enchash
- jz .noenc
- mov al, byte [esi+519] ; FSZ_SuperBlock.flags >> 4 (enctype)
- and al, 0F0h
- jz @f
- prot_realmode
- real_print loader.name
- real_print panic
- mov esi, nocipher
- call real_printfunc
- real_protmode
- jmp .err
- @@: push edi
- prot_realmode
- .passagain: real_print passphrase
- ; get passphrase from user
- mov di, pass
- mov byte [di], 0
- .getchar: call real_getchar
- cmp al, 27 ; Esc
- jne @f
- real_print clrdecrypt
- jmp .err
- @@: cmp al, 8 ; Backspace
- jne @f
- cmp di, pass
- je .getchar
- mov byte [di], 0
- dec di
- jmp .getchar
- @@: cmp al, 13 ; Enter
- je .gotpass
- cmp al, 10
- je .gotpass
- cmp al, ' '
- jb .getchar
- cmp di, pass+255
- jge .getchar
- mov word [di], ax
- inc di
- jmp .getchar
- .gotpass: push esi
- real_protmode
- mov esi, pass
- mov ecx, edi
- sub ecx, esi
- mov dword [pl], ecx
- call crc32_calc
- prot_realmode
- pop esi
- cmp dword [esi+520], edx
- je .passok
- real_print badpass
- jmp .passagain
- .passok: real_print decrypting
- real_protmode
- ; decrypt initrd
- call sha_init
- mov ecx, dword [pl]
- mov ebx, pass
- call sha_upd
- mov ecx, 6
- mov ebx, esi
- add ebx, 512 ; FSZ_SuperBlock.magic
- call sha_upd
- mov edi, chk
- call sha_final
- mov edi, esi
- add edi, 680 ; FSZ_SuperBlock.encrypt
- mov cl, 32
- xor ebx, ebx
- @@: mov al, byte [edi]
- xor byte [chk+ebx], al
- xor eax, eax
- stosb
- inc ebx
- dec cl
- jnz @b
- stosd
- call sha_init
- mov ecx, 32
- mov ebx, chk
- call sha_upd
- mov edi, iv
- call sha_final
- mov eax, dword [esi+528] ; FSZ_SuperBlock.numsec
- mov dword [pl], eax
- xor eax, eax
- inc eax
- mov dword [_i], eax ; skip first sector
- mov ebx, esi
- add ebx, 4096
- push esi
- .decrypt: mov esi, iv
- mov edi, chk
- xor ecx, ecx
- mov cl, 32/4
- repnz movsd
- mov cx, 4096
- .nextblk: mov al, bl
- and al, 31
- jnz @f
- push ebx
- push ecx
- call sha_init
- mov ecx, 32
- mov ebx, chk
- call sha_upd
- mov ecx, 4
- mov ebx, _i
- call sha_upd
- mov edi, chk
- call sha_final
- pop ecx
- pop ebx
- mov edx, edi
- @@: mov al, byte [edx]
- xor byte [ebx], al
- mov al, byte [edx+32]
- xor byte [ebx], al
- inc ebx
- inc edx
- dec cx
- jnz .nextblk
- inc dword [_i]
- mov eax, dword [_i]
- cmp eax, dword [pl]
- jne .decrypt
- mov esi, dword [esp]
- mov edi, esi
- add edi, 680 ; FSZ_SuperBlock.encrypt
- mov cl, 8
- xor eax, eax
- mov dword[esi+520], eax
- repnz stosd
- add esi, 512
- mov ecx, 508
- call crc32_calc
- pop esi
- mov dword [esi+1020], edx ; FSZ_SuperBlock.chksum
- ; clear console message
- prot_realmode
- real_print clrdecrypt
- real_protmode
- pop edi
- ; get root dir inode
- .noenc: mov dword [_i], 1024
- mov al, byte [esi+520] ; FSZ_SuperBlock.flags
- bt ax, 0 ; FSZ_SB_BIGINODE?
- jnc @f
- mov dword [_i], 2048
- @@: mov eax, dword [esi+560] ; FSZ_SuperBlock.rootdirfid
- shl eax, 12
- add esi, eax
- cmp dword [esi], 'FSIN'
- je @f
- .nolib: mov esi, nolib
- .err: xor ecx, ecx
- ret
- .nocore: mov esi, nocore
- jmp .err
- @@: ; it has inlined data?
- .again: mov eax, dword [esi+448] ; FSZ_Inode.sec
- add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
- cmp dword [esi], 'FSDR'
- je .srchdir
- ; no, locate the data
- mov ecx, dword [esi]
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- cmp dword [esi], 'FSDR'
- je .srchdir
- ; inlined sector directory or list?
- shl ecx, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, ecx
- cmp dword [esi], 'FSDR'
- jne .nolib
- .srchdir: ; find sys/
- mov ecx, dword [esi+16] ; FSZ_DirEntHeader.numentries
- mov eax, dword [edi]
- @@: add esi, 128 ; directories than
- cmp dword [esi+16], eax
- je @f
- dec ecx
- jnz @b
- jmp .nolib
- ; found, get it's inode
- @@:
- mov eax, dword [esi]
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- cmp dword [esi], 'FSIN'
- jne .nolib
- ;this is not bullet proof
- add edi, 4
- cmp byte [edi+3], '/'
- je .again
- ; it has inlined data?
- mov eax, dword [esi+448] ; FSZ_Inode.sec
- add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
- cmp dword [esi], 'FSDR'
- je .srchcore
- ; no, locate the data
- mov ecx, dword [esi]
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- cmp dword [esi], 'FSDR'
- je .srchdir
- ; inlined sector directory or list?
- shl ecx, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, ecx
- cmp dword [esi], 'FSDR'
- jne .nolib
- .srchcore: ; find filename
- mov ecx, dword [esi+16] ; FSZ_DirEntHeader.numentries
- ;filename, 8 characters supported
- mov eax, dword [edi]
- mov edx, dword [edi+4]
- @@: add esi, 128
- cmp dword [esi+20], edx
- jne .not
- cmp dword [esi+16], eax
- je @f
- .not: dec ecx
- jnz @b
- jmp .nocore
- ; found, get it's inode
- @@: mov eax, dword [esi]
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- cmp dword [esi], 'FSIN'
- jne .nocore
- ; get data
- mov eax, dword [esi+448] ; FSZ_Inode.sec
- mov ecx, dword [esi+464] ; FSZ_Inode.size
- or eax, eax
- jz .nocore
- ; inline? (FSZ_Inode.sec == inode)
- mov ebx, esi
- shr ebx, 12
- cmp eax, ebx
- jne .notinline
- mov bl, byte [esi+488] ; FSZ_Inode.flags
- add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata
- and bl, 01Fh
- jnz @f
- ret
- @@: mov eax, dword[esi]
- jmp @f
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- ret
- .notinline:
- mov bl, byte [esi+488] ; FSZ_Inode.flags
- mov bh, bl
- and bl, 0Fh
- shr bh, 4
- add bl, bh ; 0 = direct, no seclist, 1 = indirect or seclist
- or bl, bl
- jz @f
- shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- mov eax, dword [esi] ; first FSZ_SectorList.sec
- @@: shl eax, 12
- mov esi, dword [bootboot.initrd_ptr]
- add esi, eax
- ret
- ; ----------- Minix3 FS ----------
- ; Find the kernel on initrd (must be defragmented)
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- mfs_initrd:
- cmp word[esi + 1048], 'ZM'
- jne .err
- ; *((uint16_t*)(initrd_p + 1052));
- xor ebx, ebx
- mov bx, word [esi + 1052]
- ; (2 + *((uint16_t*)(initrd_p + 1030)) + *((uint16_t*)(initrd_p + 1032))) * bs;
- xor edx, edx
- xor eax, eax
- mov ax, word [esi + 1030]
- mov dx, word [esi + 1032]
- add eax, edx
- add eax, 2
- mul ebx
- mov dword [.tbl], eax
- ; initrd_p + ino_tbl;
- add eax, esi
- mov dword [.ino], eax
- .again: mov ecx, edi
- @@: inc ecx
- cmp byte [ecx], '/'
- je @f
- cmp byte [ecx], 0
- jnz @b
- @@: ; initrd_p + *((uint32_t*)(ino + 24)) * bs;
- mov eax, dword [.ino]
- mov eax, dword [eax + 24]
- xor ebx, ebx
- mov bx, word [esi + 1052]
- mul ebx
- add eax, esi
- mov edx, ebx
- shr edx, 6
- ; if(*((uint32_t*)d) && !memcmp(s, d + 4, e - s) && !d[e - s])
- .srchdir: cmp dword [eax], 0
- jnz .next
- push edi
- push eax
- add eax, 4
- @@: mov bl, byte [eax]
- cmp byte [edi], bl
- jne .nomatch
- inc eax
- inc edi
- cmp edi, ecx
- jne @b
- ; initrd_p + ino_tbl + (*((uint32_t*)d) - 1) * 64;
- pop eax
- pop edi
- mov eax, dword [eax]
- dec eax
- shl eax, 6
- add eax, dword [.tbl]
- add eax, esi
- mov dword [.ino], eax
- cmp byte [ecx], 0
- jnz @f
- ; *((uint32_t*)(ino + 8))
- mov ecx, dword [eax + 8]
- ; initrd_p + *((uint32_t*)(ino + 24)) * bs;
- mov eax, dword [eax + 24]
- xor ebx, ebx
- mov bx, word [esi + 1052]
- mul ebx
- add esi, eax
- ret
- @@: mov edi, ecx
- inc edi
- jmp .again
- .nomatch: pop eax
- pop edi
- .next: add eax, 64
- dec edx
- jz .err
- cmp byte[eax + 4], 0
- jnz .srchdir
- .err: xor ecx, ecx
- ret
- .tbl: dd 0
- .ino: dd 0
- ; ----------- cpio ----------
- ; Find the kernel on initrd
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- cpio_initrd:
- ; upper bound
- mov ebx, ecx
- xor ecx, ecx
- ; strlen(kernel)
- mov eax, edi
- or eax, eax
- jz .err
- cmp byte [eax], 0
- jz .err
- xor ecx, ecx
- @@: inc ecx
- inc eax
- cmp byte [eax], 0
- jnz @b
- mov dword [.ks], ecx
- ; while(ptr.magic=='070707' && ptr<limit)
- .next: cmp esi, ebx
- jae .err
- mov eax, '0707'
- cmp dword [esi], eax ; cpio magic
- jne .err
- cmp word [esi+4], ax ; hpodc
- je @f
- cmp word [esi+4], '01' ; newc
- je .newc
- cmp word [esi+4], '02' ; crc
- je .newc
- .err: xor ecx, ecx
- ret
- @@: mov eax, esi ; filename len
- add eax, 8*6+11
- mov ecx, 6
- call prot_oct2bin
- mov dword [.ns], eax
- mov eax, esi ; filesize
- add eax, 8*6+11+6
- mov ecx, 11
- call prot_oct2bin
- mov dword [.fs], eax
- push esi ; name equals?
- push edi
- add esi, 9*6+2*11
- mov ecx, dword [.ks]
- cmp word [esi], './'
- jne .notcurdir
- add esi, 2
- sub ecx, 2
- .notcurdir: repz cmpsb
- pop edi
- pop esi
- jz @f
- add esi, 76 ; no skip this record
- add esi, dword [.ns] ; and check the next one
- add esi, dword [.fs]
- jmp .next
- @@: add esi, 76 ; found! esi=data
- add esi, dword [.ns]
- mov ecx, dword [.fs] ; ecx=size
- ret
- .newc: mov edx, esi ; filename len
- add esi, 8*11+6
- mov ecx, 8
- call prot_hex2bin
- mov dword [.ns], eax
- mov esi, edx ; filesize
- add esi, 8*6+6
- mov ecx, 8
- call prot_hex2bin
- mov dword [.fs], eax
- mov esi, edx
- push esi ; name equals?
- push edi
- add esi, 110
- mov ecx, dword [.ks]
- cmp word [esi], './'
- jne .notcudir
- add esi, 2
- sub ecx, 2
- .notcudir: repz cmpsb
- pop edi
- pop esi
- jz @f
- mov eax, 113 ; no skip this record
- add eax, dword [.ns] ; and check the next one
- and al, 0FCh
- add esi, eax
- mov eax, dword [.fs]
- add eax, 3
- and al, 0FCh
- add esi, eax
- cmp dword [esi], '0707' ; cpio magic
- jne .err
- jmp .newc
- @@: mov eax, 113 ; found! esi=data
- add eax, dword [.ns]
- and al, 0FCh
- add esi, eax
- mov ecx, dword [.fs] ; ecx=size
- ret
- .ks: dd 0
- .ns: dd 0
- .fs: dd 0
- ; ----------- tar ----------
- ; Find the kernel on initrd
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- tar_initrd:
- ; upper bound
- mov ebx, ecx
- xor ecx, ecx
- ; strlen(kernel)
- mov eax, edi
- or eax, eax
- jz .err
- cmp byte [eax], 0
- jz .err
- xor ecx, ecx
- @@: inc ecx
- inc eax
- cmp byte [eax], 0
- jnz @b
- mov dword [.ks], ecx
- ; while(ptr.magic=='ustar' && ptr<limit)
- .next: cmp esi, ebx
- jae .err
- cmp dword [esi+257], 'usta' ; tar magic
- jne .err
- cmp byte [esi+261], 'r' ; tar magic
- je @f
- .err: xor ecx, ecx
- ret
- @@: mov eax, esi ; filesize
- add eax, 07ch
- mov ecx, 11
- call prot_oct2bin
- mov dword [.fs], eax
- push esi ; name equals?
- push edi
- mov ecx, dword [.ks]
- cmp word [esi], './'
- jne .notcurdir
- add esi, 2
- sub ecx, 2
- .notcurdir: repz cmpsb
- pop edi
- pop esi
- jz @f
- add esi, 512 ; no skip this record
- mov eax, dword [.fs] ; and check the next one
- add eax, 511
- shr eax, 9
- shl eax, 9
- add esi, eax
- jmp .next
- @@: add esi, 512 ; found! esi=data
- mov ecx, dword [.fs] ; ecx=size
- ret
- .ks: dd 0
- .fs: dd 0
- ; ----------- SFS ----------
- ; Find the kernel on Stupid File System
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- sfs_initrd:
- ; check magic
- ; 1.0, Brendan's version
- mov byte [.ver], 0
- cmp word [esi+01ACh], 'SF'
- jne @f
- cmp byte [esi+01AEh], 'S'
- je .ok
- ; 1.1, BenLunt's version
- @@: cmp word [esi+01A6h], 'SF'
- jne .err
- cmp byte [esi+01A8h], 'S'
- jne .err
- inc byte [.ver]
- ; upper bound
- .ok: mov ebx, ecx
- xor ecx, ecx
- ; strlen(kernel)
- mov eax, edi
- or eax, eax
- jz .err
- cmp byte [eax], 0
- jz .err
- xor ecx, ecx
- @@: inc ecx
- inc eax
- cmp byte [eax], 0
- jnz @b
- mov dword [.ks], ecx
- ; get block size
- xor eax, eax
- inc eax
- xor ecx, ecx
- mov cl, byte [esi+01BCh]
- cmp byte [.ver], 0
- jz @f
- mov cl, byte [esi+01B6h]
- @@: add cl, 7
- shl eax, cl
- mov dword [.bs], ecx
- ; get index area, base + totalblocks*blocksize - indexsize
- xor edx, edx
- mov eax, dword [esi+01B0h] ; total number of blocks
- cmp byte [.ver], 0
- jz @f
- mov eax, dword [esi+01AAh] ; total number of blocks
- @@: mul ecx
- add eax, esi
- mov ebx, eax
- mov edx, dword [esi+01A4h] ; size of index area
- cmp byte [.ver], 0
- jz @f
- mov edx, dword [esi+019Eh] ; size of index area
- @@: sub eax, edx
- mov edx, esi
- mov esi, eax
- cmp byte [esi], 02h ; got Starting Marker Entry?
- jne .err
- ; iterate on index until we reach end or Volume Identifier
- .nextindex: cmp esi, ebx
- jae .err
- cmp byte [esi], 01h
- je .err
- add esi, 64
- cmp byte [esi], 12h ; file entry?
- jne .nextindex
- push esi ; name equals?
- push edi
- mov ecx, dword [.ks]
- add esi, 022h
- add esi, dword [.ver]
- repz cmpsb
- pop edi
- pop esi
- jnz .nextindex
- mov ebx, esi
- mov eax, dword [esi+0Ah] ; start_block
- cmp byte [.ver], 0
- jz @f
- mov eax, dword [esi+0Bh] ; start_block
- @@: mov esi, edx
- xor edx, edx
- mov ecx, dword [.bs]
- mul ecx ; * blocksize
- add esi, eax ; base +
- ; found! esi=data, ecx=size
- mov ecx, dword [ebx+01Ah] ; file_length
- cmp byte [.ver], 0
- jz @f
- mov ecx, dword [ebx+01Bh] ; file_length
- @@: ret
- .err: xor ecx, ecx
- ret
- .ks: dd 0
- .bs: dd 0
- .ver: dd 0
- ; ----------- JamesMolloy's ----------
- ; Find the kernel on initrd
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- jamesm_initrd:
- ; no real magic, so we assume initrd contains at least one file...
- cmp word [esi+2], 0
- jne .err
- cmp byte [esi+4], 0BFh
- jne .err
- ; upper bound
- xor ecx, ecx
- ; strlen(kernel)
- mov eax, edi
- or eax, eax
- jz .err
- cmp byte [eax], 0
- jz .err
- xor ecx, ecx
- @@: inc ecx
- inc eax
- cmp byte [eax], 0
- jnz @b
- mov dword [.ks], ecx
- mov ebx, esi
- ; edx=*(int*)initrd_p
- lodsd
- mov edx, eax
- ; for(i=0;i<nf && ptr[0]==0xBF;i++)
- @@: lodsb
- cmp al, 0BFh
- jne .err
- push esi ; name equals?
- push edi
- mov ecx, dword [.ks]
- repz cmpsb
- pop edi
- pop esi
- jz @f
- add esi, 72
- dec dx
- jnz @b
- .err: xor ecx, ecx
- ret
- @@: mov ecx, dword [esi+68]
- mov esi, dword [esi+64]
- add esi, ebx
- ret
- .ks: dd 0
- ; ----------- echfs ----------
- ; Find the kernel on initrd
- ; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
- ; OUT: On Success
- ; esi: pointer to the first byte, ecx: size in bytes
- ; On Error
- ; ecx: 0
- ech_initrd:
- cmp dword [esi + 4], '_ECH'
- jne .err
- cmp dword [esi + 8], '_FS_'
- jne .err
- mov edx, esi
- mov esi, dword[esi + 12]
- shl esi, 3
- add esi, 16*512
- mov ebx, 0FFFFFFFFh
- .again: xor ecx, ecx
- @@: inc cx
- cmp byte [edi + ecx], 0
- jz @f
- cmp byte [edi + ecx], '/'
- jne @b
- @@:
- .next: cmp dword [esi], 0
- jz .err
- cmp dword [esi], ebx
- jne .not
- cmp byte [esi + ecx + 9], 0
- jnz .not
- push esi
- push edi
- push ecx
- add esi, 9
- rep cmpsb
- pop ecx
- pop edi
- pop esi
- jnz .not
- mov ebx, dword [esi + 240]
- add edi, ecx
- inc edi
- cmp byte [edi - 1], '/'
- je .again
- cmp byte [esi + 8], 0
- jnz .err
- mov ecx, dword [esi + 248]
- mov esi, ebx
- shl esi, 9
- add esi, edx
- ret
- .not: add esi, 256
- jmp .next
- .err: xor ecx, ecx
- ret
|