📄 bootlace.inc
字号:
cmpl $0xfffffff7, ABS(fstypes) movl $ABS(msg_option_fstypes_for_mbr), %ecx jnz 4f /* error */ cmpl $((pre_stage2_start - _start1) / 512), ABS(probed_sectors_per_track) movl $ABS(msg_sectors_per_track), %ecx jb 4f /* error */ cmpl $0xffffffff, ABS(install_partition) movl $ABS(msg_option_install_partition_not_implemented), %ecx je 1f jmp 4f /* error */ /* EBX holds the file descriptor number or 0 if it is BIOS drive */ /* move partition table forward to the beginning of the 17th sector */ movl $ABS(mbr_63_sectors + 0x01be), %esi movl $ABS(mbr_63_sectors + 0x2000), %edi movl $0x10, %ecx # 0x10 dwords = 0x40 bytes cld repz movsl /* initialize the current_partition number */ movzbl ABS(install_partition), %eax movl %eax, ABS(current_partition)3: /* load the next partition and modify the boot record */ call 0f /* partition */ jc 3f /* done */ call 2f /* write to file */ incl ABS(current_partition) movw ABS(install_partition), %ax addb %ah, %al /* Max partition number for install */ cmpb %al, ABS(current_partition) jbe 3b3: /* all partitions have been installed. */ xorl %eax, %eax # exit code = 0 #ifdef __DOS_16 movb $0x4c, %ah // EXIT - TERMINATE WITH RETURN CODE in AL int $0x21 // call DOS#else xchgl %eax, %ebx # move exit code in EAX to EBX movl $1, %eax # sys_exit int $0x80#endif ret1://---------------------------------------------------------------------------- /* backup mbr */ /* auto backup */ cmpl $1, ABS(backup_mbr) jnz 1f /* check if the second sector consists of 512 dups of one byte */ movb ABS(mbr_63_sectors + 0x200), %al movl $ABS(mbr_63_sectors + 0x200), %edi movl $0x200, %ecx cld repz scasb jz 1f # yes, enable backup movl $0, ABS(backup_mbr) # no, do not backup1://---------------------------------------------------------------------------- cmpl $0, ABS(backup_mbr) jz 1f # will not backup movl $ABS(mbr_63_sectors), %esi movl $ABS(mbr_63_sectors + 0x200), %edi movl $0x80, %ecx # 0x80 dwords = 0x200 bytes cld repz movsl1://---------------------------------------------------------------------------- /* copy byte 0000 to 01b7 of grldr.mbr to ABS(mbr_63_sectors) */ movl $ABS(_start1), %esi movl $ABS(mbr_63_sectors), %edi movl $0x6e, %ecx # 0x6e dwords = 0x1b8 bytes cld repz movsl /* locate the BPB sector */ movl ABS(probed_sectors_per_track), %eax movl $63, %esi testl %ebx, %ebx jz 1f # BIOS drive movl %eax, %esi1: shll $9, %esi addl $ABS(mbr_63_sectors), %esi /* ESI points to BPB sector */ /* check if it has a valid FAT BPB */ cmpw $512, 0x0B(iSI) jne 1f cmpw %ax, 0x18(iSI) jne 1f cmpl %eax, 0x1C(iSI) #; partition must start at the second track jne 1f movl ABS(probed_heads), %eax cmpw %ax, 0x1A(iSI) jne 1f movb 0x0D(iSI), %cl testb %cl, %cl jz 1f movw $128, %ax divb %cl testb %ah, %ah jnz 1f movw 0x0E(iSI), %cx jcxz 1f movb 0x10(iSI), %al # number of FATs decw %ax cmpb $1, %al ja 1f /* copy the BPB to ABS(mbr_63_sectors) */ addl $0x0B, %esi movl $ABS(mbr_63_sectors + 0x0B), %edi movl $(0x5A - 0x0B), %ecx cld repz movsb /* modify reserved sectors */ movl $ABS(mbr_63_sectors), %esi movl 0x1C(iSI), %eax #; EAX=sectors per track addw %ax, 0x0E(iSI) /* modify total sectors word */ movw 0x13(iSI), %ax #; EAX hi word = 0 testw %ax, %ax jz 3f addw 0x1C(iSI), %ax movw %ax, 0x13(iSI)3: /* modify total sectors dword */ movl 0x20(iSI), %eax testl %eax, %eax jz 3f addl 0x1C(iSI), %eax movl %eax, 0x20(iSI)3: /* clear the hidden sectors */ xorl %eax, %eax movl %eax, 0x1C(iSI)1: /* modify ABS(mbr_floppy) bit */ movb ABS(mbr_floppy), %al andb $0x01, %al movb %al, ABS(mbr_63_sectors + 2) /* modify ABS(mbr_osbr) bit */ movb ABS(mbr_osbr), %al andb $0x01, %al shlb $1, %al orb %al, ABS(mbr_63_sectors + 2) /* modify ABS(duce) bit */ movb ABS(duce), %al andb $0x01, %al shlb $2, %al orb %al, ABS(mbr_63_sectors + 2) /* modify ABS(boot_prevmbr) bit */ movb ABS(boot_prevmbr), %al notb %al andb $0x01, %al rorb $1, %al orb %al, ABS(mbr_63_sectors) + 2 /* modify ABS(time_out) byte */ movb ABS(time_out), %al movb %al, ABS(mbr_63_sectors) + 3 /* modify ABS(hot_key) byte */ movw ABS(hot_key), %ax movw %ax, ABS(mbr_63_sectors) + 4 /* modify ABS(preferred_drive) byte */ movb ABS(preferred_drive), %al movb %al, ABS(mbr_63_sectors) + 6 /* modify ABS(preferred_partition) byte */ movb ABS(preferred_partition), %al movb %al, ABS(mbr_63_sectors) + 7 /* copy byte 0400 and the rest of grldr.mbr to ABS(mbr_63_sectors) */ movl $ABS(_start1 + 0x400), %esi movl $ABS(mbr_63_sectors + 0x400), %edi movl $((pre_stage2_start - _start1 - 0x400) / 4), %ecx cld repz movsl//----------------------------------------------------------------------------2: /* label for the above floppy code to jump */ /* OK. Now write file! */ xorl %eax, %eax cmpw $2, ABS(read_only) jne 3f pushl %ebx # file descriptor, or 0 if specified BIOS drive /* for safety, don't write too many sectors */ cmpl $0xffffffff, ABS(install_partition) jne 1f cmpl $0xffffffff, ABS(floppy) je 2f1: cmpl $4, ABS(sectors_to_write) jbe 1f movl $4, ABS(sectors_to_write) jmp 1f2: cmpl $((pre_stage2_start - _start1) / 512), ABS(sectors_to_write) jbe 1f movl $((pre_stage2_start - _start1) / 512), ABS(sectors_to_write)1:#ifdef __DOS_16 xorl %eax, %eax cmpl $0xff, ABS(bios_drive_number) je 1f movb $0x03, %ah # write to disk movb ABS(sectors_to_write), %al// cmpl $0xffffffff, ABS(floppy)// je 2f// movb $4, %al # write 4 sectors if it is floppy//2: movw $ABS(mbr_63_sectors), %bx movw $1, %cx movw ABS(bios_drive_number), %dx int $0x13 jmp 2f1: //WRITE TO FILE OR DEVICE //AH = 40h //BX = file handle //CX = number of bytes to write //DS:DX -> data to write //Return: //CF clear if successful AX = number of bytes actually written //CF set on error AX = error code (05h,06h) movl $0x4000, %eax movl ABS(sectors_to_write), %ecx shll $9, %ecx //movl $(pre_stage2_start - _start1), %ecx// cmpl $0xffffffff, ABS(floppy)// je 1f// movl $0x800, %ecx # write 4 sectors if it is floppy//1: movl $ABS(mbr_63_sectors), %edx int $0x212: jnc 1f negl %eax1:#else /* ssize_t write(int fd, const void *buf, size_t count) */ movl $4, %eax # sys_write movl $ABS(mbr_63_sectors), %ecx movl ABS(sectors_to_write), %edx shll $9, %edx //movl $(pre_stage2_start - _start1), %edx # length of grldr.mbr// cmpl $0xffffffff, ABS(floppy)// je 1f// movl $0x800, %edx # write 4 sectors if it is floppy//1: int $0x80#endif popl %ebx # file descriptor, or 0 if specified BIOS drive3: cmpl $0xffffffff, ABS(install_partition) je 3f /* for install_partition, SF=0 when success, SF=1 when failure */ testl %eax, %eax ret3: testl %eax, %eax movl $ABS(msg_write_file), %ecx js 4f /* error *///---------------------------------------------------------------------------- cmpl $0xffffffff, ABS(floppy) jne 3f movl $ABS(msg_geometry_S), %ecx call 8f /* linux_print */ movl ABS(probed_sectors_per_track), %eax call 6f /* print decimal number */ movl $ABS(msg_geometry_H), %ecx call 8f /* linux_print */ movl ABS(probed_heads), %eax call 6f /* print decimal number */ movl $ABS(msg_success), %ecx call 8f /* linux_print */3://success: # EBX=file descriptor, or 0 if specified BIOS drive xorl %eax, %eax # exit code = 0 jmp 1f //error:4: # EBX=file descriptor, or 0 if specified BIOS drive testl %ecx, %ecx jz 2f call 8f /* linux_print */2: movl $ABS(msg_usage), %ecx call 8f /* linux_print */ movl $1, %eax # exit code = 11: testl %ebx, %ebx jz 1f pushl %eax # exit code#ifdef __DOS_16 movb $0x3e, %ah // close file (BX = file handle) int $0x21 jnc 2f negl %eax /* EAX < 0 */2:#else /* int close(int fd); */ movl $6, %eax # sys_close int $0x80#endif movl $ABS(msg_close_file), %ecx testl %eax, %eax popl %eax # exit code jns 1f call 8f /* linux_print *///exit:1:#ifdef __DOS_16 movb $0x4c, %ah // EXIT - TERMINATE WITH RETURN CODE in AL int $0x21 // call DOS#else xchgl %eax, %ebx # move exit code in EAX to EBX movl $1, %eax # sys_exit int $0x80#endif ret//----------------------------------------------------------------------------//floppy:5: pushal /* Beforehand, try MBR */ /* ESI=$ABS(mbr_63_sectors) */ cld cmpw $0xAA55, 0x1fe(iSI) jne 1f pushl %esi pushl %edi pushl %ebx /* has a valid partition table ? */ movb $0, %bl /* count valid partition entries */ addl $0x1be, %esi3: cmpl $(ABS(mbr_63_sectors) + 0x1fe), %esi jnb 3f /* partition table is OK */ movl $4, %ecx movl %esi, %edi2: lodsl negl %eax jc 2f loop 2b /* empty entry, check next */ jmp 3b2: /* non-empty entry */ movl %edi, %esi lodsw shlb $1, %al /* boot indicator */ jnz 2f lodsw andb $63, %al jz 2f lodsw lodsw andb $63, %al jz 2f lodsl negl %eax jnc 2f lodsl negl %eax jnc 2f incb %bl jmp 3b2: stc /* invalid partition table */3: popl %eax popl %edi popl %esi xchgl %eax, %ebx jc 1f testb %al, %al jz 1f /* MBR write not allowed */ movl $0, ABS(sectors_to_write) movl $ABS(msg_fstype_mbr_deny), %ecx call 8f /* linux_print */ stc popal ret1: /* First, try ext2 */ cmpw $0xEF53, 0x438(iSI) /* Magic signature */ jnz 1f xorl %eax, %eax cmpl %eax, 0x400(iSI) /* s_inodes_count */ jz 1f cmpl %eax, 0x404(iSI) /* s_blocks_count */ jz 1f// cmpw %ax, 0x458(iSI) /* s_inode_size, usually 0x80 */// jz 1f cmpl %eax, 0x420(iSI) /* s_blocks_per_group */ jz 1f cmpl %eax, 0x428(iSI) /* s_inodes_per_group */ jz 1f movl 0x414(iSI), %eax /* s_first_data_block */ movw %ax, %bx /* BX=1 for 1K block, 0 otherwise */ shrl $1, %eax /* must be 0 */ jnz 1f movl 0x418(iSI), %ecx /* s_log_block_size */ cmpl $4, %ecx /* max size of block is 16K */ ja 1f negw %cx /* CF=0 for 1K block, CF=1 otherwise */ adcw %ax, %bx /* EAX=0 */ decw %bx jnz 1f /* BX = 0 */ movl $ABS(_start1 + 0x826), %edi /* inode size in the 5th sector */ movw $0x80, %ax /* EXT2_GOOD_OLD_INODE_SIZE */ movw %ax, (iDI) /* inode size */ movl 0x44C(iSI), %ecx /* ECX=s_rev_level */ jecxz 3f /* EXT2_GOOD_OLD_REV */ movw 0x458(iSI), %ax /* AX=s_inode_size */ testw %ax, %ax jz 1f /* invalid inode size */ pushw %ax pushw %dx movb 0x418(iSI), %cl /* s_log_block_size */ addb $10, %cl xorw %dx, %dx /* DX=0 */ incw %dx /* DX=1 */ shlw %cl, %dx /* DX=block size in bytes */ xchgw %ax, %cx /* CX=s_inode_size */ xchgw %ax, %dx /* AX=block size in bytes */ xorw %dx, %dx /* DX:AX=block size in bytes */ divw %cx /* quo=AX, rem=DX */ testw %dx, %dx popw %dx popw %ax jnz 1f /* invalid inode size */ movw %ax, (iDI) /* inode size */3: /* BX = 0 */ /* super block is sane */ /* is EXT2 allowed write? */ testl $0x10, ABS(fstypes) jnz 2f /* EXT2 write not allowed */ movl $0, ABS(sectors_to_write) movl $ABS(msg_fstype_ext2_deny), %ecx call 8f /* linux_print */ stc popal ret2: /* write to ext2 boot area */ cld movl $ABS(_start1 + 0x800), %esi /* points to the 5th sector */ movl $ABS(mbr_63_sectors), %edi lodsw /* The first 2 byte: short jmp */ LEAL 0x400(%edi), %esi /* ESI points to super block */ stosw /* lba indicator byte is not used. so we shouldn't touch it. */ /* check lba-chs-mode specified, 1 byte */ cmpl $-1, ABS(lba) /* lba-chs-mode not specified? */ je 2f /* yes, do nothing. */#if 0 movb $0x42, %al /* initialize to lba mode. */ cmpl $0, ABS(lba) /* chs ? */ jnz 10f /* no, it is not chs.*/ movb $0x02, %al /* yes, it is chs. */10:#else /* if specified lba or chs, we simply place a 0x90. */ movb $0x90, %al#endif stosb decl %edi2: addl $(1+10), %edi /* skip 10-byte OEM name */ /* Sectors per block, byte */ movb 0x18(iSI), %cl /* s_log_block_size */ movl $2, %eax shlw %cl, %ax stosb /* Bytes per block, word */ shlw $9, %ax /* block size is word wide */ stosw /* Pointers covered by an indirect block, dword */ /* Pointers per block, dword */ shrw $2, %ax pushl %eax /* Pointers per block */ addb $8, %cl shll %cl, %eax stosl /* Pointers covered by an indirect block */ popl %eax stosl /* Pointers per block */ /* Sectors per track, word */ cmpl $0xFFFFFF3F, ABS(sectors_per_track) je 10f movb ABS(sectors_per_track), %al cbw stosw subl $2, %edi10: addl $2, %edi /* Number of heads, word */ cmpl $0xFFFF00FF, ABS(heads) je 10f movw ABS(heads), %ax stosw subl $2, %edi10: addl $2, %edi /* hidden sectors(i.e., partition start), dword */ movb ABS(floppy), %al /* partition number(0xFF for floppy) */ cmpb $0xff, %al jne 10f /* real floppy */ cmpl $0xffffffff, ABS(start_sector) sete %al movzbl %al, %eax addl ABS(start_sector), %eax stosl jmp 11f10: /* hard drive partition */ addl $4, %edi cmpl $0xffffffff, ABS(start_sector) je 11f movl ABS(start_sector), %eax subl $4, %edi stosl11: /* total sectors, dword */ movl %es:(iDI), %eax cmpl %eax, ABS(total_sectors) jbe 10f movl ABS(total_sectors), %eax10: stosl /* drive number, byte */ //this byte is not used. incl %edi /* partition number, byte */ movb ABS(floppy), %al stosb /* reserved, word */ incl %edi incl %edi /* Number of inodes per group, dword */ movl 0x28(iSI), %eax /* s_inodes_per_group */ stosl /* block number for group descriptors, dword */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -