📄 tboot.s
字号:
; tboot.s;; Load HFS volume on any partition(main or ext); writen by tpu, base on boot0 source from Darwin;; Set to 1 to enable obscure debug messages.DEBUG EQU 0; Various constants.kBoot0Segment EQU 0x0000kBoot0Stack EQU 0xFFF0 ; boot0 stack pointerkBoot0LoadAddr EQU 0x7C00 ; boot0 load addresskBoot0RelocAddr EQU 0xE000 ; boot0 relocated addresskBoot2Sectors EQU 126 ; sectors to load for boot2kBoot2Address EQU 0x0000 ; boot2 load addresskBoot2Segment EQU 0x2000 ; boot2 load segmentkMBRBuffer EQU 0x1000 ; MBR buffer addresskExtBuffer EQU 0x1200 ; MBR buffer addresskPartTableOffset EQU 0x1bekMBRPartTable EQU kMBRBuffer + kPartTableOffsetkExtPartTable EQU kExtBuffer + kPartTableOffsetkSectorBytes EQU 512 ; sector size in byteskBootSignature EQU 0xAA55 ; boot sector signaturekPartCount EQU 4 ; number of paritions per tablekPartTypeBoot EQU 0xab ; boot2 partition typekPartTypeUFS EQU 0xa8 ; UFS partition typekPartTypeHFS EQU 0xaf ; HFS partition typekPartTypeExtDOS EQU 0x05 ; DOS extended partition typekPartTypeExtWin EQU 0x0f ; Windows extended partition typekPartTypeExtLinux EQU 0x85 ; Linux extended partition typekPartActive EQU 0x80kDriveNumber EQU 0x80; Format of fdisk partition entry.; The symbol 'part_size' is automatically defined as an `EQU'; giving the size of the structure. struc part.bootid: resb 1 ; bootable or not .head: resb 1 ; starting head, sector, cylinder.sect: resb 1 ;.cyl: resb 1 ;.type: resb 1 ; partition type.endhead resb 1 ; ending head, sector, cylinder.endsect: resb 1 ;.endcyl: resb 1 ;.lba: resd 1 ; starting lba.sectors resd 1 ; size in sectors endstruc; Macros.%macro DebugCharMacro 1 mov al, %1 call _putc%endmacro%if DEBUG%define putc(x) DebugCharMacro x%else%define putc(x)%endif%macro puts 1 mov si, %1 call put_string%endmacro;--------------------------------------------------------------------------; Start of text segment. SEGMENT .text ORG 0xe000 ; must match kBoot0RelocAddr;--------------------------------------------------------------------------; Boot code is loaded at 0:7C00h.start: ; Set up the stack to grow down from kBoot0Segment:kBoot0Stack. ; Interrupts should be off while the stack is being manipulated. cli ; interrupts off xor ax, ax ; zero ax mov ss, ax ; ss <- 0 mov sp, kBoot0Stack ; sp <- top of stack sti ; reenable interrupts mov es, ax ; es <- 0 mov ds, ax ; ds <- 0 ; Relocate boot0 code. mov si, kBoot0LoadAddr ; si <- source mov di, kBoot0RelocAddr ; di <- destination cld ; auto-increment SI and/or DI registers mov cx, kSectorBytes/2 ; copy 256 words repnz movsw ; repeat string move (word) operation ; Code relocated, jump to start_reloc in relocated location. jmp 0:start_reloc;--------------------------------------------------------------------------; Start execution from the relocated location.;start_reloc:.loop_next_drive: ; Clear drive flags. xor eax, eax mov [first_part], eax ; clear EBIOS LBA offset mov [this_part], eax%if DEBUG putc('D') mov al, dl call putb putc(' ')%endif ; Read MBR sector to memory. mov al, 1 ; load one sector mov bx, kMBRBuffer ; MBR load address xor ecx, ecx call load jc .next_drive mov di, kMBRBuffer mov si, kMBRBuffer+kPartTableOffset cmp WORD [si + part_size * kPartCount], kBootSignature jne .next_drive ; Signature error ; Look for the HFS partition in the MBR partition table call find_boot ; will not return on success.next_drive: inc dl ; next drive number test dl, 0x4 ; went through all 4 drives? jz .loop_next_drive ; not yet, loop again puts part_error_str.hang: hlt jmp SHORT .hang;--------------------------------------------------------------------------; Find the HFS partition and load the booter from the partition.;--------------------------------------------------------------------------find_boot: mov cx, 4 ; number of partition entries per table.loop_part: push cx push si%if DEBUG mov al, [si + part.type] call putb putc(' ') mov eax, [si + part.lba] call putd putc(10) putc(13)%endif mov eax, [si + part.lba] mov bl, [si + part.type] ; print partition type cmp bl, kPartTypeExtLinux ; Extended Linux je .ext_check cmp bl, kPartTypeExtDOS ; Extended DOS je .ext_check cmp bl, kPartTypeExtWin ; Extended Windows(95) jne .nonext.ext_check: cmp di, kMBRBuffer jnz .ext_not_mbr mov [first_part], eax xor eax, eax.ext_not_mbr: mov [this_part], eax ; Read extended partition table mov ecx, eax mov al, 1 ; load one sector mov bx, kExtBuffer ; extended load address call load jc .next_part mov si, kExtBuffer+kPartTableOffset cmp WORD [si + part_size * kPartCount], kBootSignature jne .next_part ; Signature error push di mov di, kExtBuffer call find_boot pop di cmp di, kMBRBuffer jnz .next_part xor eax, eax mov [this_part], eax mov [first_part], eax.next_part: pop si pop cx add si, part_size ; advance SI to next partition entry loop .loop_part ; loop through all partition entries.exit_find ret.nonext: cmp bl, 0 je .next_part cmp bl, kPartTypeHFS je .found_part cmp bl, kPartTypeUFS je .found_part cmp bl, kPartTypeBoot jne .next_part.found_part: add eax, [this_part] mov ecx, eax add eax, [first_part] mov [si+part.lba], eax ; Found boot partition, read boot sector to memory. mov bx, kBoot0LoadAddr mov al, 1 call load jc .next_part ; load error, keep looking? putc("F") cmp WORD [bx + 510], kBootSignature jnz .next_part ; patch boot1h mov eax, [0x7cbb] cmp eax, 0x20000200 jnz .no_patch mov eax, 0x00007d40 mov [0x7cbb], eax push si mov si, patch_code_start mov di, 0x7d40 mov cx, (patch_code_end-patch_code_start) cld repnz movsb pop si.no_patch: ; Jump to partition booter. The drive number is already in register DL. ; SI is pointing to the modified partition entry. jmp kBoot0Segment:kBoot0LoadAddr;--------------------------------------------------------------------------; load - Read sectors from a partition using LBA addressing.;--------------------------------------------------------------------------load: pushad ; save all registers mov bp, sp ; save current SP ;push DWORD 0 ; offset 12, upper 32-bit LBA push ds ; For sake of saving memory, push ds ; push DS register, which is 0. add ecx, [first_part] ; offset 8, lower 32-bit LBA push ecx push es ; offset 6, memory segment push bx ; offset 4, memory offset xor ah, ah ; offset 3, must be 0 push ax ; offset 2, number of sectors push WORD 16 ; offset 0-1, packet size%if DEBUG putc('L') mov eax, ecx call putd putc(10) putc(13)%endif mov si, sp mov ah, 0x42 int 0x13 mov sp, bp ; restore SP popad ret;--------------------------------------------------------------------------; Write a string to the console.;; Arguments:; DS:SI pointer to a NULL terminated string.;; Clobber list:; AX, BX, SI;put_string mov bx, 1 ; BH=0, BL=1 (blue) cld ; increment SI after each lodsb call.loop lodsb ; load a byte from DS:SI into AL cmp al, 0 ; Is it a NULL? je .exit ; yes, all done mov ah, 0xE ; INT10 Func 0xE int 0x10 ; display byte in tty mode jmp short .loop.exit ret%if DEBUG; Show a DWORD value.putd ror eax, 16 call putw ror eax, 16; Show a WORD value.putw ror ax, 8 call putb ror ax, 8; Show a BYTE value.putb ror al, 4 call put_nibble ror al, 4; Show 4 bit value.put_nibble push eax and al, 0x0f add al, 0x30 cmp al, 0x39 jna .pascii add al, 0x07.pascii call _putc pop eax ret; Show a ASCII character to the console._putc pusha mov bx, 1 mov ah, 0x0e int 0x10 popa ret%endif ;DEBUGpatch_code_start: ; patch boot2: SelectBootVolume mov di, 0x39ac mov eax, [es:di] cmp eax, 0x01a8da45 jne .no_patch mov al, 2 mov [es:di+3], al.no_patch: ; Jump to boot2. The drive number is already in register DL. jmp kBoot2Segment:kBoot2Address + kSectorBytespatch_code_end:; NULL terminated strings.part_error_str: db 'No HFS partition found', 10, 13, 0;--------------------------------------------------------------------------; Pad the rest of the 512 byte sized booter with zeroes. The last; two bytes is the mandatory boot sector signature.pad_boot times 510-($-$$) db 0 dw kBootSignature ABSOLUTE 0xE400; In memory variables.first_part resd 1 ; starting LBA of the intial extended partition.this_part resd 1 ; starting LBA of the current extended partition. part_base resd 1 END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -