;* ;* 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 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 ; encrypted initrd? cmp dword [esi+708], 0 ; FSZ_SuperBlock.enchash jz .noenc mov al, byte [esi+519] ; FSZ_SuperBlock.enctype or al, al 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+708], 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, 28 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, 28 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] 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 mov bl, byte [esi+488] ; FSZ_Inode.flags ; inline cmp bl, 0FFh ; FSZ_IN_FLAG_INLINE jne @f add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata ret ; direct data block @@: or bl, bl ; FSZ_IN_FLAG_DIRECT je .load ; inlined sector directory or sector list @@: cmp bl, 07Fh ; FSZ_IN_FLAG_SDINLINE je @f cmp bl, 080h ; FSZ_IN_FLAG_SECLIST je @f cmp bl, 1 ; FSZ_IN_FLAG_SD jne .nocore shl eax, 12 mov esi, dword [bootboot.initrd_ptr] add esi, eax mov eax, dword [esi] ; first FSZ_SectorList.sec jmp .load @@: add esi, dword[_i] ; FSZ_Inode.[big|small].inlinedata ; sector directory at esi, file size in ecx mov eax, dword [esi] ; first FSZ_SectorList.sec .load: shl eax, 12 mov esi, dword [bootboot.initrd_ptr] add esi, eax ret ; ----------- 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