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