📄 grldrstart.s
字号:
popw %ax /* AX=0 */ jc 5f /* floppy failure, issue "Error" and hang */ cwd /* DX=0 */ xchgw %ax, %cx /* this moves CL to AL, and CX=0 */ andb $63, %al /* AL=sectors per track */ jz 5f /* invalid value. floppy failure. hangs */ //movw $1, %cx incw %cx jmp 7b5:Error_or_prev_MBR: /* GRLDR not found, print "Error" or launch previous MBR */ movw $(message_string - _start1), %si call print_message /* CS:SI points to message string */3: jmp 3bint13: pushw %ds pushw %es// pushw %bx pushw %dx pushw %si pushw %di pushw %bp stc int $0x13 popw %bp popw %di popw %si popw %dx// popw %bx popw %es popw %ds ret#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL))filesystem_boot: /* The partition boot record successfully modified, just boot it */ /* * The boot might fail, but we want to take back the control. * So we save the registers now. */ pushw %ds pushw %es pushal /* DS=CS=GRLDR_CS, ES=FS_BOOT */ /* save GRLDR_CS */ movw %es, %bx # save old ES to BX cli lgdt gdt - _start1 movl %cr0, %eax orb $1, %al movl %eax, %cr0 movw $8, %si movw %si, %es xorl %esi, %esi xorl %edi, %edi movl $(0x9000 / 4), %ecx cld repz movsl movw $16, %si movw %si, %es andb $0xfe, %al movl %eax, %cr0 movw %bx, %es # restore ES from BX /* move FS_BOOT:0000 to 0:7c00 */#if 0 /* for single sector boot record */ movw $0x0200, %cx /* move 2 sectors, the old FS_BOOT:0000 will keep untouched. */#else /* for 4-sector NTFS boot record */ movw $0x0400, %cx /* move 4 sectors, the old FS_BOOT:0000 will keep untouched. */#endif xorw %si, %si pushw %si /* SI=0, for the segment of 0000:7c00 */ movw $0x7c00, %di pushw %di /* DI=0x7c00, for the offset of 0000:7c00 */ pushw %es /* ES=FS_BOOT */ popw %ds /* DS=FS_BOOT */ pushw %si /* SI=0 */ popw %es /* ES=0 */ cld repz movsw movw $MONITOR, %di movw $(restore_GRLDR_CS - _start1), %si movw $((gdt_end - restore_GRLDR_CS) / 4), %cx cld repz cs movsl /* CS segment override prefix(=0x2E) */ pushw %es /* ES=0 */ popw %ds /* DS=0 */ sti lret //ljmp $0, $0x7c00#endiftry_next_partition: cli movw $GRLDR_CS, %ax movw %ax, %ss movw $(0x9000-36), %sp sti /* restore the registers and continue */ popal popw %es popw %ds jmp add_sub_si#if (defined(GRLDR_MBR)) || (defined(GRLDR_INSTALL))read_disk_with_reset_and_dec_di: pushaw// int $0x13 call int13 popaw jnc 3f pushaw xorw %ax, %ax// int $0x13 call int13 popaw decw %di stc3: ret#endif /* prints string CS:SI (modifies AX BX SI) */3: //xorw %bx, %bx /* video page 0 */ movb $0x0e, %ah /* print char in AL */ int $0x10 /* via TTY mode */print_message: lodsb %cs:(%si), %al /* get token */ cmpb $0, %al /* end of string? */ jne 3b retmessage_string:#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) .ascii "\r\nMissing helper.\0"#else .ascii "\r\nMissing MBR-helper.\0"#endif#;buggy_bios_string:#;#; .ascii "\r\nBuggy BIOS!\0" /* Make sure the above code does not occupy the partition table */#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* offset value here must be less than or equal to 0x1be */ . = . - ((. - _start1) / 0x1bf)#else /* offset value here must be less than or equal to 0x1b8 */ . = . - ((. - _start1) / 0x1b9)#endif /* The following code may occupy the same area as the partition table */#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL)) /* we are not booted from MBR. So we can reuse the area of partition * table for our code. */ . = _start1 + 0x1becdrom_check: /* DS=CS points to the sector start. */ /* BX segment points to near the end of GRLDR image. */ popw %ax /* old return IP */ /* set BX as the new safe stack. */ movw %bx, %ss movw $0xFFF0, %sp pushw %ax /* old return IP */ /* check if DL is no-emulation-mode bootable CDROM. */ pushw %ds cmpb $0x80, %dl jb 1f /* not a valid no-emulation-mode cdrom drive number */ cmpw $0xAA55, 0x7FE /* 2048 bytes loaded? */ jne 1f// cmpw $0xAA55, 0x5FE /* 2048 bytes loaded? */// jne 1f movw $0x0180, %si movw $0x4B01, %ax pushw $0x0040 //.byte 0x6A, 0x40 popw %ds pushw %ds popw %es movb $0x13, (%si) call int13// pushw %ds// pushw %dx// int $0x13// popw %dx// popw %ds /* ignore CF */#; jc 2f /* not in emulation mode */ xorl %eax, %eax xorw %bp, %bp testb $0x0F, 1(%si) /* boot media type is No Emulation? */ jnz 2f /* no, it simulates floppy or hard disk. */ cmpb %dl, 2(%si) /* drive number */ jnz 2f /* invalid drive */ /* OK! it is no-emulation-mode cdrom drive. */ movl 4(%si), %eax /* LBA of GRLDR */ incw %bp2: jmp cdrom_helper1: popw %ds ret#else . = _start1 + 0x1fe /* boot signature */#endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) *//* partition entries in the extended partitions will overwrite code here upto * 0x3fd. * * the extended partition entries will occupy a temp area at 0x9be00-0x9c3ff */#if (defined(GRLDR_MBR)) || (defined(GRLDR_INSTALL)) .word 0xaa55#endif . = _start1 + 0x200/* if it is in the Master Boot Track, the second sector can be used to backup * the previously working MBR, typically, the MS MBR. if the backup copy of * the MBR cannot boot(because, e.g., it depends on another sector of code * that does not exist for now), then please do not set the ending signature * to 0xAA55, that is to say, if the signature is already 0xAA55, you should * change it to another value(for example, 0x0000). */#if (! defined(GRLDR_INSTALL))#if 0print_cl: pushaw movw %cx, %ax movb $16, %cl divb %cl # quo=AL, rem=AH orw $0x3030, %ax cmpb $0x39, %ah jbe 1f addb $7, %ah1: cmpb $0x39, %al jbe 1f addb $7, %al1: movb %ah, %cl xorw %bx, %bx movb $0x0e, %ah int $0x10 movb $0x0e, %ah movb %cl, %al int $0x10 movw $0x0e20, %ax int $0x10 popaw ret#else#if 0 .word 5, 0x47, 0x52, 0x4c, 0x44, 0x52, 4, 0x24 .word 0x49, 0x33, 0x30, 0xe000, 0, 0x3000, 0, 0#else .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90#endif .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90#endif . = _start1 + 0x256 /* cmdcons comes here */#if 0 jmp 1f#else .byte 0x90, 0x90#endif . = _start1 + 0x258 .byte 0x90, 0x90 . = _start1 + 0x25a .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 .byte 0x90, 0x90 . = _start1 + 0x26a1: //movw %cs, %ax //movw %ax, %ds //jmp single_boot_sector /* a value < 0x80 here means we are not booted from no-emulation-mode * bootable CD. */ movb $0x7F, %dl jmp _start1#endif /* (! defined(GRLDR_INSTALL)) */#if (! defined(GRLDR_MBR)) && (! defined(GRLDR_INSTALL))cdrom_helper: /* IP and old_DS is on the stack. */ /* DS=ES=40h */ /* Stack is high and safe. */ /* EAX is LBA. if EAX==0, LBA is unknown. */ /* check if the first sector is the same as the current one */ /* load the first sector onto the sector immediately follows */1: pushw %cs popw %bx /* BX=CS=old_DS=load_segment */ addw $0x0080, %bx /* buffer segment */ movw %bx, %es /* ES changed! */ call load_cd_sector /* compare the two sectors */ movw $0x200, %cx xorw %si, %si xorw %di, %di cld cs repz cmpsl je load_the_rest /* 1st sector is ok, continue */not_grldr: testw %bp, %bp jz 2f xorw %bp, %bp xorl %eax, %eax2: incl %eax jnz 1b /* try next */cd_no_grldr: popw %ds /* DS=load_segment */ # Here we use error message and routine in FAT32 boot sector # which is also inside the 2048-byte CD sector. movw $(msg_BootError_32 - _start1), %si jmp boot_error_32 load_cd_sector: /* input: EAX LBA * BX buffer segment(buffer offset=0) * DS 0x40 (or another safe one) * output: * SI changed(=0x1A0) * 16 bytes at DS:SI destroyed */ movw $0x1A0, %si /* disk address packet */ movl $0x00010010, (%si) /* load 1 sector each time. */ movw $0, 4(%si) /* buffer offset=0 */ movw %bx, 6(%si) /* buffer segment */ movl %eax, 8(%si) /* LBA lo 32 bits */ movl $0, 12(%si) /* LBA hi 32 bits */// pushw %ds// pushw %es pushal movb $0x42, %ah call int13// int $0x13 popal// popw %es// popw %ds retload_the_rest: /* load all sectors (except the first one) */ /* EAX = first sector(LBA) of GRLDR */ pushl %eax pushw %cs popw %bx /* BX=CS=old_DS=load_segment */// movw %bx, %es /* 6144 = 0x1800 = 3 sectors > 4KB, this is for the additional 4KB-preset-menu at the end of grldr */ movw $((grldr_signature - _start1 + 4 + STAGE2_SIZE - 1 + 6144) / 2048), %cx /* sectors to load */1: incl %eax /* next sector */ addw $0x0080, %bx /* buffer segment */ call load_cd_sector loop 1b /* loading is completed. BX=segment of the last sector. */ subw $0x0181, %bx /* decw %bx */ movw %bx, %ds popl %eax// subl $((grldr_signature - _start1 + 4 + STAGE2_SIZE - 1 + 6144) / 2048), %eax /* check the ending signature */ cmpl $0xCE1A02B0, ((grldr_signature - _start1 + 4 + STAGE2_SIZE - 1) % 2048) + 13 jne not_grldr#; je grldr_real_start /* yes. boot it! */#; /* it is not our grldr image, return and use MBR-helper. */#;#;4:#; //jmp grldr_real_start#; popw %ds#; retgrldr_real_start: #; FAT_12_16 no longer be used. So comment out. #;je 1f /* jc 1f */ #;//ZF=0 /* CF cleared, so we are coming from FAT_12_16 */ #;popw %dx /* discard the cluster number */ #;popw %dx /* this is our boot_drive/boot_partition */ #;1: #; The partition number for no-emulation-mode bootable CDROM will be #; set to 0xFF later(in common.c). So comment out. #;cli #;movw %cs, %ax #;cmpw $0x1000, %ax #;jne 1f #; #;/* CS=0x1000, may be booted from ext2 or no-emulation-mode CDROM */ #; #;cmpw $0x1000, %di #;jne 2f #;cmpw $0x7c00, %bp #;jne 2f #;movw %es, %ax #;cmpw $0x1000, %ax #;jbe 2f #;cmpw $0x7c00, %si #;jbe 2f #;movl %edx, %eax #;shrl $16, %eax #;jnz 2f #;jecxz 1f // booted from ext2 partition #;2:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -