mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
Additional BPs
This commit is contained in:
commit
d7d2aff8e7
6 changed files with 4222 additions and 0 deletions
25
Makefile
Normal file
25
Makefile
Normal file
|
@ -0,0 +1,25 @@
|
|||
all: bootboot.bin bootboot.sym refresh
|
||||
|
||||
bootboot.bin: bootboot.asm
|
||||
@echo " src x86_64-bios (MultiBoot / BIOS)"
|
||||
@cat bootboot.asm | grep -v "^public" | grep -v "format ELF64" >bb.asm
|
||||
@fasm bb.asm bootboot.bin >/dev/null
|
||||
@rm bb.asm
|
||||
|
||||
bootboot.sym: bootboot.asm
|
||||
@echo " sym bootboot.sym"
|
||||
@fasm bootboot.asm bootboot.elf >/dev/null
|
||||
@nm bootboot.elf | sort | sed 's/\ A\ /\ /g' > bootboot.sym
|
||||
@printf "fffffffff8000000 mmio\nfffffffffc000000 fb\nffffffffffe00000 bootboot\nffffffffffe01000 environment\nffffffffffe02000 _start\n" >>bootboot.sym
|
||||
@rm bootboot.elf
|
||||
|
||||
disk-x86.img: disk-x86.img.gz
|
||||
@gzip -d -k disk-x86.img.gz
|
||||
|
||||
refresh: bootboot.bin disk-x86.img
|
||||
@echo " dd bootboot.bin to disk-x86.img"
|
||||
@dd if=bootboot.bin of=disk-x86.img bs=1 seek=120832 conv=notrunc 2>/dev/null
|
||||
|
||||
clean:
|
||||
@rm bootboot.bin bootboot.sym disk-x86.img >/dev/null 2>/dev/null || true
|
||||
|
2916
bootboot.asm
Normal file
2916
bootboot.asm
Normal file
File diff suppressed because it is too large
Load diff
125
bootboot.inc
Normal file
125
bootboot.inc
Normal file
|
@ -0,0 +1,125 @@
|
|||
;*
|
||||
;* x86_64-bios/bootboot.inc
|
||||
;*
|
||||
;* Copyright (C) 2017 - 2020 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 The BOOTBOOT structure
|
||||
;*
|
||||
; ------ !!! WARNING: MUST MATCH ../bootboot.h !!! ------
|
||||
|
||||
bootboot = 8000h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; this define is in the 18th line of bootboot.h
|
||||
bootboot_MAGIC equ 'BOOT'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; minimum protocol level:
|
||||
; hardcoded kernel name, static kernel memory addresses
|
||||
PROTOCOL_MINIMAL equ 0
|
||||
; static protocol level:
|
||||
; kernel name parsed from environment, static kernel memory addresses
|
||||
PROTOCOL_STATIC equ 1
|
||||
; dynamic protocol level:
|
||||
; kernel name parsed from environment, kernel memory addresses parsed from ELF symbols
|
||||
PROTOCOL_DYNAMIC equ 2
|
||||
; big-endian flag
|
||||
PROTOCOL_BIGENDIAN equ 080h
|
||||
|
||||
; loader types, just informational
|
||||
LOADER_BIOS equ 0
|
||||
LOADER_UEFI equ 4
|
||||
LOADER_RPI equ 8
|
||||
LOADER_COREBOOT equ 16
|
||||
|
||||
; framebuffer pixel format, only 32 bits supported
|
||||
FB_ARGB equ 0
|
||||
FB_RGBA equ 1
|
||||
FB_ABGR equ 2
|
||||
FB_BGRA equ 3
|
||||
|
||||
|
||||
|
||||
; mmap entry, type is stored in least significant tetrad of size
|
||||
virtual at 0
|
||||
mmap_ent.ptr: dq 0
|
||||
mmap_ent.size: dq 0
|
||||
end virtual
|
||||
; we don't have entry field macros for asm
|
||||
; realsize = size & 0xFFFFFFFFFFF0
|
||||
; type = size & 0xF
|
||||
|
||||
|
||||
MMAP_USED equ 0
|
||||
MMAP_FREE equ 1
|
||||
MMAP_ACPI equ 2
|
||||
MMAP_MMIO equ 3
|
||||
|
||||
INITRD_MAXSIZE equ 16 ; Mb
|
||||
|
||||
virtual at bootboot
|
||||
; first 64 bytes is platform independent
|
||||
bootboot.magic: dd 0
|
||||
bootboot.size: dd 0
|
||||
bootboot.protocol: db 1
|
||||
bootboot.fb_type: db 0
|
||||
bootboot.numcores: dw 0
|
||||
bootboot.bspid: dw 0
|
||||
bootboot.timezone: dw 0
|
||||
bootboot.datetime: dq 0
|
||||
bootboot.initrd_ptr: dq 0
|
||||
bootboot.initrd_size: dq 0
|
||||
bootboot.fb_ptr: dq 0
|
||||
bootboot.fb_size: dd 0
|
||||
bootboot.fb_width: dd 0
|
||||
bootboot.fb_height: dd 0
|
||||
bootboot.fb_scanline: dd 0
|
||||
|
||||
; the rest (64 bytes) is platform specific
|
||||
|
||||
; x86_64
|
||||
bootboot.acpi_ptr: dq 0
|
||||
bootboot.smbi_ptr: dq 0
|
||||
bootboot.efi_ptr: dq 0
|
||||
bootboot.mp_ptr: dq 0
|
||||
bootboot.unused: dq 0,0,0,0
|
||||
|
||||
bootboot.mmap:
|
||||
end virtual
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
disk-x86.img.gz
Normal file
BIN
disk-x86.img.gz
Normal file
Binary file not shown.
656
fs.inc
Normal file
656
fs.inc
Normal file
|
@ -0,0 +1,656 @@
|
|||
;*
|
||||
;* x86_64-bios/fs.inc
|
||||
;*
|
||||
;* Copyright (C) 2017 - 2020 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 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+518] ; FSZ_SuperBlock.flags
|
||||
shr al, 2
|
||||
and al, 7
|
||||
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+518] ; FSZ_SuperBlock.flags
|
||||
bt ax, 0 ; FSZ_FLAG_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+17], 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+21], edx
|
||||
jne .not
|
||||
cmp dword [esi+17], 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<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
|
500
tinf.inc
Normal file
500
tinf.inc
Normal file
|
@ -0,0 +1,500 @@
|
|||
;*
|
||||
;* x86_64-bios/tinf.inc
|
||||
;*
|
||||
;* Copyright (C) 2017 - 2020 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 Tiny inflate, ported after tinflate.c by bzt
|
||||
;*
|
||||
|
||||
;IN:
|
||||
; esi: gzipped initrd (without gzip header)
|
||||
; edi: output buffer (guaranteed to be big enough)
|
||||
; ecx: output buffer size
|
||||
tinf_uncompress:
|
||||
push ecx
|
||||
push edi
|
||||
mov edi, tinf_bss_start
|
||||
mov ecx, tinf_bss_end-tinf_bss_start+1
|
||||
xor al, al
|
||||
repnz stosb
|
||||
pop edi
|
||||
pop ecx
|
||||
mov dword [d_end], ecx
|
||||
add dword [d_end], edi
|
||||
.again:
|
||||
; start a new block
|
||||
cmp byte [d_btype], 255
|
||||
jne .notst
|
||||
; read final block flag
|
||||
.next_blk: call tinf_getbit
|
||||
mov byte [d_bfinal], al
|
||||
; read block type
|
||||
xor ebx, ebx
|
||||
mov cl, 2
|
||||
call tinf_read_bits
|
||||
mov byte [d_btype], al
|
||||
; build fixed huffman trees
|
||||
cmp al, 1
|
||||
jne @f
|
||||
call tinf_build_fixed_trees
|
||||
xor al, al
|
||||
; decode trees from stream
|
||||
@@: cmp al, 2
|
||||
jne @f
|
||||
call tinf_decode_trees
|
||||
@@:
|
||||
.notst:
|
||||
; process current block
|
||||
cmp byte [d_btype], 0
|
||||
jnz @f
|
||||
; decompress uncompressed block
|
||||
call tinf_inflate_uncompressed_block
|
||||
JMP .procend
|
||||
@@: cmp byte [d_btype], 1
|
||||
je @f
|
||||
cmp byte [d_btype], 2
|
||||
jne tinf_err
|
||||
; decompress block with fixed/dyanamic huffman trees
|
||||
; trees were decoded previously, so it's the same routine for both
|
||||
@@: call tinf_inflate_block_data
|
||||
.procend: cmp al, 1
|
||||
jne @f
|
||||
cmp byte [d_bfinal], 0
|
||||
; the block has ended (without producing more data), but we
|
||||
; can't return without data, so start procesing next block
|
||||
jz .next_blk
|
||||
ret
|
||||
@@: or al, al
|
||||
jnz tinf_err
|
||||
cmp edi, dword [d_end]
|
||||
jbe .again
|
||||
ret
|
||||
|
||||
; build the fixed huffman trees
|
||||
tinf_build_fixed_trees:
|
||||
push edi
|
||||
xor ecx, ecx
|
||||
xor eax, eax
|
||||
; build fixed length tree
|
||||
mov cl, 7
|
||||
mov edi, d_ltree_table
|
||||
repnz stosb
|
||||
mov al, 24
|
||||
stosb
|
||||
mov al, 152
|
||||
stosb
|
||||
mov al, 112
|
||||
stosb
|
||||
mov edi, d_ltree_trans
|
||||
|
||||
mov cl, 24
|
||||
mov ax, 256
|
||||
@@: stosw
|
||||
inc ax
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
mov cl, 144
|
||||
xor ax, ax
|
||||
@@: stosw
|
||||
inc ax
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
mov cl, 8
|
||||
mov ax, 280
|
||||
@@: stosw
|
||||
inc ax
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
mov cl, 112
|
||||
mov ax, 144
|
||||
@@: stosw
|
||||
inc ax
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
; build fixed distance tree
|
||||
mov cl, 5
|
||||
mov edi, d_dtree_table
|
||||
xor al, al
|
||||
repnz stosb
|
||||
mov al, 32
|
||||
stosb
|
||||
|
||||
mov edi, d_dtree_trans
|
||||
mov cl, 32
|
||||
xor ax, ax
|
||||
@@: stosw
|
||||
inc ax
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
pop edi
|
||||
ret
|
||||
|
||||
;IN:
|
||||
; ebp: TINF_TREE
|
||||
; ebx: lengths
|
||||
; ecx: num
|
||||
tinf_build_tree:
|
||||
push edi
|
||||
xor eax, eax
|
||||
; clear code length count table
|
||||
mov edi, ebp
|
||||
stosd ; for(i=0;i<16;i++) table[i]=0;
|
||||
stosd
|
||||
stosd
|
||||
stosd
|
||||
|
||||
; scan symbol lengths, and sum code length counts
|
||||
push ebx
|
||||
push ecx
|
||||
@@: mov al, byte [ebx] ;lengths[i]
|
||||
inc ebx
|
||||
inc byte [ebp+eax] ;table[lengths[i]]++
|
||||
dec cx
|
||||
jnz @b
|
||||
mov byte [ebp], 0
|
||||
|
||||
; compute offset table for distribution sort
|
||||
mov cl, 16
|
||||
xor edx, edx ;i
|
||||
xor ebx, ebx ;sum
|
||||
xor eax, eax
|
||||
@@: mov word [offs+2*edx], bx
|
||||
mov al, byte [ebp+edx]
|
||||
add ebx, eax
|
||||
inc edx
|
||||
dec cl
|
||||
jnz @b
|
||||
|
||||
pop ecx
|
||||
pop ebx ;lengths
|
||||
|
||||
; create code->symbol translation table (symbols sorted by code)
|
||||
xor eax, eax ;i
|
||||
@@: cmp byte [ebx], 0
|
||||
jz .null
|
||||
xor edx, edx
|
||||
mov dl, byte [ebx] ;lengths[i]
|
||||
inc word [offs+2*edx]
|
||||
mov dx, word [offs+2*edx]
|
||||
dec dx
|
||||
mov word [ebp+2*edx+16], ax
|
||||
.null: inc ebx
|
||||
inc eax
|
||||
dec cx
|
||||
jnz @b
|
||||
|
||||
pop edi
|
||||
ret
|
||||
|
||||
tinf_decode_trees:
|
||||
mov word [num], 0
|
||||
|
||||
; get 5 bits HLIT (257-286)
|
||||
xor ecx, ecx
|
||||
mov cl, 5
|
||||
mov ebx, 257
|
||||
call tinf_read_bits
|
||||
mov word [hlit], ax
|
||||
mov word [num], ax
|
||||
|
||||
; get 5 bits HDIST (1-32)
|
||||
mov cl, 5
|
||||
xor ebx, ebx
|
||||
inc ebx
|
||||
call tinf_read_bits
|
||||
mov word [hdist], ax
|
||||
add word [num], ax
|
||||
|
||||
; get 4 bits HCLEN (4-19)
|
||||
mov cl, 4
|
||||
mov ebx, ecx
|
||||
call tinf_read_bits
|
||||
mov word [hclen], ax
|
||||
|
||||
push edi
|
||||
mov cl, 19
|
||||
mov edi, lengths
|
||||
xor ax, ax
|
||||
repnz stosw
|
||||
pop edi
|
||||
|
||||
; read code lengths for code length alphabet
|
||||
mov edx, clcidx
|
||||
; get 3 bits code length (0-7)
|
||||
@@: mov cx, 3
|
||||
xor ebx, ebx
|
||||
call tinf_read_bits
|
||||
xor ebx, ebx
|
||||
mov bl, byte [edx] ;clcidx[i]
|
||||
mov byte[ebx+lengths], al
|
||||
inc edx
|
||||
dec word [hclen]
|
||||
jnz @b
|
||||
|
||||
; build code length tree, temporarily use length tree
|
||||
mov ebp, d_ltree
|
||||
mov ebx, lengths
|
||||
xor ecx, ecx
|
||||
mov cl, 19
|
||||
call tinf_build_tree
|
||||
|
||||
; decode code lengths for the dynamic trees
|
||||
mov edx, lengths
|
||||
.decode: mov ebp, d_ltree
|
||||
call tinf_decode_symbol
|
||||
xor ebx, ebx
|
||||
cmp al, 16
|
||||
jne .not16
|
||||
; copy previous code length 3-6 times (read 2 bits)
|
||||
mov cl, 2
|
||||
mov bl, 3
|
||||
call tinf_read_bits
|
||||
mov cx, ax
|
||||
mov al, byte [edx-1] ;lengths[num-1]
|
||||
@@: mov byte [edx], al
|
||||
inc edx
|
||||
dec word [num]
|
||||
dec cl
|
||||
jnz @b
|
||||
jmp .next
|
||||
|
||||
.not16: cmp al, 17
|
||||
jne .not17
|
||||
; repeat code length 0 for 3-10 times (read 3 bits)
|
||||
mov cl, 3
|
||||
mov bl, cl
|
||||
call tinf_read_bits
|
||||
mov cx, ax
|
||||
@@: mov byte [edx], 0
|
||||
inc edx
|
||||
dec word [num]
|
||||
dec cl
|
||||
jnz @b
|
||||
jmp .next
|
||||
|
||||
.not17: cmp al, 18
|
||||
jne .not18
|
||||
; repeat code length 0 for 11-138 times (read 7 bits)
|
||||
mov cl, 7
|
||||
mov bl, 11
|
||||
call tinf_read_bits
|
||||
mov cx, ax
|
||||
@@: mov byte [edx], 0
|
||||
inc edx
|
||||
dec word [num]
|
||||
dec cl
|
||||
jnz @b
|
||||
jmp .next
|
||||
|
||||
.not18: ; values 0-15 represent the actual code lengths
|
||||
mov byte [edx], al
|
||||
inc edx
|
||||
dec word [num]
|
||||
|
||||
.next: cmp word [num], 0
|
||||
jnz .decode
|
||||
|
||||
; build dynamic trees
|
||||
mov ebp, d_ltree
|
||||
mov ebx, lengths
|
||||
xor ecx, ecx
|
||||
mov cx, word [hlit]
|
||||
call tinf_build_tree
|
||||
|
||||
mov ebp, d_dtree
|
||||
mov ebx, lengths
|
||||
xor ecx, ecx
|
||||
mov cx, word [hlit]
|
||||
add ebx, ecx
|
||||
mov cx, word [hdist]
|
||||
call tinf_build_tree
|
||||
ret
|
||||
|
||||
;OUT:
|
||||
; al: status
|
||||
tinf_inflate_block_data:
|
||||
cmp word [d_curlen], 0
|
||||
jne .notnull
|
||||
mov ebp, d_ltree
|
||||
call tinf_decode_symbol
|
||||
; literal byte
|
||||
cmp ax, 256
|
||||
jae @f
|
||||
stosb
|
||||
xor al, al
|
||||
ret
|
||||
@@: cmp ax, 256
|
||||
jne @f
|
||||
; end of block
|
||||
mov al, 1
|
||||
ret
|
||||
@@: ; substring from sliding dictionary
|
||||
sub eax, 257
|
||||
; possibly get more bits from length code
|
||||
xor ecx, ecx
|
||||
mov cl, byte [length_bits+eax]
|
||||
xor ebx, ebx
|
||||
mov bx, word [length_base+2*eax]
|
||||
call tinf_read_bits
|
||||
mov word [d_curlen], ax
|
||||
; possibly get more bits from distance code
|
||||
mov ebp, d_dtree
|
||||
call tinf_decode_symbol
|
||||
xor ecx, ecx
|
||||
mov cl, byte [dist_bits+eax]
|
||||
xor ebx, ebx
|
||||
mov bx, word [dists_base+2*eax]
|
||||
call tinf_read_bits
|
||||
cmp dword [d_dict_ring], 0
|
||||
neg eax
|
||||
mov dword [d_lzOff], eax
|
||||
.notnull: mov eax, edi
|
||||
add eax, dword [d_lzOff]
|
||||
mov al, byte [eax]
|
||||
stosb
|
||||
@@: dec word [d_curlen]
|
||||
xor al, al
|
||||
ret
|
||||
|
||||
;OUT:
|
||||
; al: status
|
||||
tinf_inflate_uncompressed_block:
|
||||
cmp word [d_curlen], 0
|
||||
jne @f
|
||||
; get length
|
||||
lodsw
|
||||
; get one's complement of length
|
||||
add esi, 2
|
||||
; increment length to properly return TINF_DONE below, without
|
||||
; producing data at the same time
|
||||
mov word [d_curlen], ax
|
||||
inc word [d_curlen]
|
||||
; make sure we start next block on a byte boundary
|
||||
mov byte [d_bitcount], 0
|
||||
@@: dec byte [d_curlen]
|
||||
cmp byte [d_curlen], 0
|
||||
jnz @f
|
||||
mov al, 1
|
||||
ret
|
||||
@@: movsb
|
||||
xor al, al
|
||||
ret
|
||||
|
||||
;OUT:
|
||||
; al,zeroflag bit
|
||||
tinf_getbit:
|
||||
mov al, byte [d_bitcount]
|
||||
or al, al
|
||||
jnz @f
|
||||
lodsb
|
||||
mov byte [d_tag], al
|
||||
mov byte [d_bitcount], 8
|
||||
@@: dec byte [d_bitcount]
|
||||
xor ax, ax
|
||||
shr byte [d_tag], 1
|
||||
adc ax, 0
|
||||
ret
|
||||
|
||||
;IN:
|
||||
; ebx: base
|
||||
; cl: num
|
||||
;OUT:
|
||||
; eax: bits
|
||||
tinf_read_bits:
|
||||
push edx
|
||||
or cl, cl
|
||||
jz .end
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
inc dl
|
||||
.next: call tinf_getbit
|
||||
jz @f
|
||||
add ebx, edx
|
||||
@@: shl edx, 1
|
||||
dec cl
|
||||
jnz .next
|
||||
.end: pop edx
|
||||
mov eax, ebx
|
||||
ret
|
||||
|
||||
;IN:
|
||||
; ebp: TINF_TREE
|
||||
;OUT:
|
||||
; eax: trans
|
||||
tinf_decode_symbol:
|
||||
push edx
|
||||
xor eax, eax
|
||||
xor ebx, ebx ;cur
|
||||
xor ecx, ecx ;len
|
||||
xor edx, edx ;sum
|
||||
; get more bits while code value is above sum
|
||||
@@: shl ebx, 1
|
||||
call tinf_getbit
|
||||
add ebx, eax
|
||||
inc ecx
|
||||
mov al, byte [ebp+ecx]
|
||||
add edx, eax
|
||||
sub ebx, eax
|
||||
jns @b
|
||||
add edx, ebx
|
||||
mov ax, word [ebp+2*edx+16]
|
||||
mov ebp, edx
|
||||
pop edx
|
||||
ret
|
||||
|
||||
tinf_err:
|
||||
mov esi, nogzip
|
||||
jmp prot_diefunc
|
||||
|
||||
length_bits:
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0
|
||||
db 1, 1, 1, 1, 2, 2, 2, 2
|
||||
db 3, 3, 3, 3, 4, 4, 4, 4
|
||||
db 5, 5, 5, 5, 0, 0, 0, 0
|
||||
length_base:
|
||||
dw 3, 4, 5, 6, 7, 8, 9, 10
|
||||
dw 11, 13, 15, 17, 19, 23, 27, 31
|
||||
dw 35, 43, 51, 59, 67, 83, 99, 115
|
||||
dw 131, 163, 195, 227, 258, 0, 0
|
||||
dist_bits:
|
||||
db 0, 0, 0, 0, 1, 1, 2, 2
|
||||
db 3, 3, 4, 4, 5, 5, 6, 6
|
||||
db 7, 7, 8, 8, 9, 9, 10, 10
|
||||
db 11, 11, 12, 12, 13, 13, 0, 0
|
||||
dists_base:
|
||||
dw 1, 2, 3, 4, 5, 7, 9, 13
|
||||
dw 17, 25, 33, 49, 65, 97, 129, 193
|
||||
dw 257, 385, 513, 769, 1025, 1537, 2049, 3073
|
||||
dw 4097, 6145, 8193, 12289, 16385, 24577, 0, 0
|
||||
clcidx:
|
||||
db 16, 17, 18, 0, 8, 7, 9, 6
|
||||
db 10, 5, 11, 4, 12, 3, 13, 2
|
||||
db 14, 1, 15
|
||||
|
||||
d_btype: db 255
|
Loading…
Reference in a new issue