📄 grub-0.95-patch1-startups
字号:
+ * Copyright (C) 2004 Tinybit(tinybit@163.net)+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.+ */++/*+ * This program is used to generate the GRLDR file.+ *+ * Use the following shell command to generate the GRLDR file:+ *+ * cat grldrstart pre_stage2 > grldr+ *+ */++#define ASM_FILE+ + .file "grldrstart.S"++ .text++ /* Tell GAS to generate 16-bit real mode instructions */++ .code16++ .globl start, _start++start:+_start:++ jmp 1f /* FAT32/NTFS routine comes to offset 0 */++ . = _start + 3 /* FAT12/FAT16 routine comes to offset 3 */++ jmp fat_12_16+1:+ /* check 7c00 */++ movw $0x7c0, %ax+ movw %ax, %ds /* DS=0x7c0 */+ movw %cs, %cx+ cmpw %ax, %cx+ ja grldr_real_start++ /* we are loaded by BIOS or another boot loader */++single_boot_sector:++ /* DS segment base address = _start, for the move operation to work */++ cli+ movw $0x9400, %ax /* hope this segment never be used by all */+ /* subsequent partition boot records */+ movw %ax, %es /* ES=0x9400 */+ movw %ax, %ss /* SS=0x9400 */+ movw $0x9000, %sp /* SS:SP=0x9d000, keep away from EBDA data */+ sti+ + movw $0x0003, %ax /* set display mode: 80*25 color text */+ int $0x10+ + /* + * 0x07c00-0x07dff This sector. Another boot loader load us here+ * 0x0d000-0x14dff partition/floppy boot track(bootsector,etc)+ * 0x94000-0x9bdff master boot track(MBR,etc,usually 63 sectors)+ * 0x9be00-0x9cfff stack+ */+#define FS_BOOT 0xd00 /* segment of partition boot track */++ movb $8, %ah /* read drive parameters, will change DX */+ movb $0x80, %dl /* BIOS drive number is in DL */+ int $0x13+ jc Error1 /* harddisk (hd0) failed, try floppy (fd0) */+ xchgw %ax, %cx /* this moves CL to AL */+ andb $63, %al /* AL=sectors per track, CF cleared */+ stc+ jz Error1 /* invalid value, try floppy (fd0) */+ movb $0x02, %ah+ movw %ax, %bp /* save AX to BP: read 1 track */+ xorw %bx, %bx+ movw $1, %cx+ movw $0x0080, %dx+ int $0x13 /* read master boot track to ES:0000 */+Error1:+ pushfw+ + /* Move the code and error messages from DS:0000 to 9400:0000, do not+ * touch the partition table+ */+ xorw %si, %si+ xorw %di, %di+ movw $223, %cx /* 223 words = 446 bytes */+ cld+ repz movsw+ cmpl $0xAA555247, 0x03fc /* "GR" 0x55 0xAA */+ jne 1f+ call move_helper+1:+ ljmp $0x9400, $(1f - _start)+1:+ pushw %ss /* SS=0x9400 */+ popw %ds /* DS=0x9400 */+ movw $0x01be, %si+ popfw+ jc try_floppy /* harddisk (hd0) failed, try floppy (fd0) */+1:+ lodsw+ movb %ah, %dh /* head number */+ lodsw+ movw %ax, %cx /* sector and cylinder number */+ jcxz 2f /* sector=0 is invalid, so assume this is an+ empty partition entry and try next entry */+ andb $63, %al+ + /* use BP to calculate the sectors to read within 1 track */+ subw %bp, %ax+ decw %ax /* decb %al */+ negb %al /* AL=sectors upto the end of the track */+7:+ movb $2, %ah+ pushw $FS_BOOT+ popw %es /* ES=FS_BOOT */+ xorw %bx, %bx+ int $0x13 /* read partition boot track to FS_BOOT:0000 */+ jc 2f /* failed, try next entry */++ /* check the existence of helper */+ cmpl $0xAA555247, 0x03fc /* "GR" 0x55 0xAA */+ jne 6f+ pushw %ds /* DS=0x9400 */+ pushw %es /* ES=FS_BOOT */+ pushal+ lcall $0x9400, $(helper_start - _start) /* find GRLDR in partition */+ popal+ popw %es+ popw %ds+ jnc 1f /* helper succeeded, so skip NTLDR and directly boot */+6:+ /* find "NTLDR" */+ movw $0x0100, %di+ movw $0x00fa, %cx+ movb $0x4e, %al /* "N" */+3:+ cld+ repnz scasb+ jcxz 2f /* "NTLDR" not found */+ movl $0x52444c54, %ebx /* "TLDR" */+ cmpl %ebx, %es:(%di)+ jnz 3b+4:+ movw $0x5247, %es:-1(%di) /* "GR" */+3:+ repnz scasb+ jcxz 4f /* all done, about to boot it! */+ cmpl %ebx, %es:(%di)+ jnz 3b+ jmp 4b+2:+ addw $12, %si+ cmpw $0x01fe, %si /* All the 4 entries checked done? */+ jb 1b /* No, check the next entry */+ ja 5f /* floppy already checked. Fail and hang */++try_floppy:++ movw $0x0202, %si /* for helper to print "(fd0)" */+ movb $0x08, %ah /* read drive parameters, will change DX */+ cwd /* DL=0 for floppy */+ int $0x13+ jc 5f /* floppy failure, issue "Error" and hang */+ xchgw %ax, %cx /* this moves CL to AL */+ andb $63, %al /* AL=sectors per track */+ jz 5f /* invalid value. floppy failure. hangs */+ xorw %dx, %dx+ movw $1, %cx+ jmp 7b++5:+#if 1+ movw $(message_string - _start), %si+ call print_message+3:+ jmp 3b+#else+ /* Error: NTLDR not found */+ movw $0x1301, %ax /* write string and move cursor */+ movw $0x0007, %bx /* page 0, white */+ movw $5, %cx /* 5 chars to display */+ cwd /* DX=0, at top left corner */+ + /* ES:BP points to string */+ movw $(message_string - _start), %bp+ pushw %cs+ popw %es+ int $0x10+3:+ jmp 3b+#endif++4:+ /* check if it is NTFS file system+ * ES:0010 -- number of FATs(byte), root dir entries(word),+ * total_sectors_short(low byte). 0 means NTFS+ */+ movl %es:0x10, %ecx+ jecxz 3f+1:+ /* 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++ /* move FS_BOOT:0000 to 0:7c00 */+ movw $0x100, %cx+ 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+ pushw %es /* ES=0 */+ popw %ds /* DS=0 */+ lret //ljmp $0, $0x7c00+3:+ /* check NTFS boot record */+ movw $0x0074, %di+ cmpl $0x680d0068, %es:(%di) /* push $0x0d00, push */+ jnz 2b /* unknown NTFS boot record, failed boot GRLDR */+ cmpl $0x8acb026a, %es:4(%di) /* 026a, retf, mov DL */+ jnz 2b /* unknown NTFS boot record, failed boot GRLDR */++ /* modify NTFS boot record */+ movw $0x0167, %di+ movb $0xea, %al /* ljmp, hand over the control to supervisor */+ stosb+ movw $(try_next_partition - _start), %ax /* offset for ljmp */+ stosw+ movw %cs, %ax /* AX=0x9400, segment for ljmp */+ stosw+ movl $0x00520047, %es:0x202+ /* With NTFS boot sectors in place, we just boot it */+ pushw %ds+ pushw %es+ pushal+ xorw %ax, %ax+ cli+ movw %ax, %ss /* SS must be 0 for NTFS */+ movw $0x7c00, %sp+ sti+ pushw %es /* ES=0xd00, segment of the real boot code */+ pushw $0x026a /* offset of the real boot code */+ lret++Error:+ jmp 5b++try_next_partition:++ cli+ movw $0x9400, %ax+ movw %ax, %ss+ movw $(0x9000-36), %sp+ sti++ /* restore the registers and continue */+ popal+ popw %es+ popw %ds+ jmp 2b++ /* prints string DS: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+ ret++message_string:+ .ascii "\r\nError"++ .byte 0++ /* Make sure the above code does not occupy the partition table */++ . = 0x177 /* offset value here must be less than or equal to 0x1be */++ /* The following code may occupy the same area as the partition table */++fat_12_16:+ pushw %bx /* starting cluster */+ movzwl 3(%si), %eax /* Reserved sectors */+ movl %eax, 8(%di) /* start sector to read */+ pushw $0x7800 /* initial segment for read buffer */+ popw %es+ movw 11(%si), %cx /* Sectors per FAT */+1:+ pushw %cx+ movb $1, %al /* number of sectors to read. Read 1 sector */+ xorw %bx, %bx+ lcall *4(%di) /* read AX sectors to ES:BX start at 8(%di) */+ popw %cx+2:+ jc Error+ movw %es, %ax+ addw $0x20, %ax+ movw %ax, %es+ incl 8(%di) /* start sector to read */+ loop 1b++ /* now FAT is at 7800:0000 - 8800:ffff. next, read GRLDR */++ pushw %cs+ popw %es /* ES:BX=2000:0000 */++1:+ popw %dx /* get the next cluster in the stack */+ pushw %dx /* save again to the stack */++ movzbw 2(%si), %ax /* sectors per cluster. Read this cluster */+ pushw %ax+ xorw %bx, %bx+ lcall *(%di) /* read the old clusters to ES:BX */+ popw %ax /* AX=number of sectors read */+ jc 2b /* Error */+ shlw $5, %ax /* AX=number of 16-byte sections read */+ /* this assumes 512-byte sector size */+ movw %es, %bx+ addw %ax, %bx+ movw %bx, %es++ popw %ax /* get the old cluster in the stack */+ call 1f /* next_cluster */+ pushw %ax /* save new cluster to the stack */+ jc 1b /* Carry set if not EOF */+ jmp grldr_real_start++1: /* function next_cluster() */++ /* input: AX = cluster number+ * output: AX = next cluster number+ * Carry cleared if EOF+ */+ + pushw %ds+ pushw %si++#if 1+ /* this assumes 512-byte sector size */+ cmpw $13, 11(%si) /* Sectors per FAT: FAT12 <= 12, FAT16 >= 16 */+#else+ /* this allows the use of 512 or 1024 or 2048-byte sector size */+ pushw %ax+ pushw %dx+ movw (%si), %ax /* AX=Bytes per sector */+ mulw 11(%si) /* Sectors per FAT */+ /* DX:AX=bytes per FAT */+ cmc+ jnc 1f /* overflow means FAT16 */+ cmpw $0x1801, %ax /* FAT12 if below(carry), FAT16 if not below */+1:+ popw %dx+ popw %ax+#endif+ pushfw++ movw %ax, %si /* SI = cluster number */+ addw %si, %si /* multiply cluster number by two */+ pushw $0x7800 /* segment for FAT */+ popw %ds+ jnc 1f+ pushw $0x8800 /* overflow. Add 0x1000 to segment */+ popw %ds+1:++ popfw+ jnc 2f++ /* FAT12 -- (Bytes per FAT <= 0x1800) -- (Sectors per FAT <= 12) */+ addw %ax, %si /* multiply cluster number by 3 ... */+ shrw $1, %si /* ... and divide by 2 */+ lodsw++ /* If the cluster number was even, the cluster value is now in+ * bits 0-11 of AX. If the cluster number was odd, the cluster+ * value is in bits 4-15, and must be shifted right 4 bits. If+ * the number was odd, CF was set in the last shift instruction.+ */++ jnc 1f+ shrw $4, %ax+1:+ andb $0x0f, %ah /* mask off the highest 4 bits */+ cmpw $0x0ff8, %ax /* check for EOF */+ jmp 4f++2:+ /* FAT16 -- (Bytes per FAT > 0x1800) -- (Sectors per FAT > 12) */+ lodsw /* AX = next cluster */+ cmpw $0xfff8, %ax /* check for EOF */++4:++#if 0+ jb 5f /* Carry stored if not EOF */+ xorw %ax, %ax /* 0 for EOF. Carry cleared */+5:+#endif++ popw %si+ popw %ds+ ret++ . = 0x1fe /* boot signature */+ .word 0xaa55++ . = 0x200++ .word 5, 0x47, 0x52, 0x4c, 0x44, 0x52, 4, 0x24+ .word 0x49, 0x33, 0x30, 0xe000, 0, 0x3000, 0, 0++ . = 0x256 /* cmdcons comes here */++ jmp 1f++ . = 0x258++ .byte 0x90, 0x90++ . = 0x26a+1:+ movw %cs, %ax+ movw %ax, %ds+ jmp single_boot_sector++grldr_real_start:+ jmp grldr_final++ . = 0x280++helper_start:+ jmp helper_real_start++move_helper:+ + movw $0x200, %si+ movw %si, %di+ movw $0xf00, %cx+ cld+ repz movsw+ ret++grldr_final:++ cli+ xorw %ax, %ax+ movw %ax, %ss+ movw $0x2000, %sp+ pushw %cs+ popw %ds+ xchgw %si, %ax /* SI=0 */+ pushw $((0x8200 - (pre_stage2_start - _start)) >> 4)+ popw %es+ xorw %di, %di+ movw $((pre_stage2_start - _start) >> 1), %cx+ cld+ repz movsw+ ljmp $0, $(1f + 0x8200 - pre_stage2_start) /* CS=0 */+1:+ movw $(0x8000 - ((pre_stage2_start - _start) >> 1)), %cx+ repz movsw+ movb $5, %bl /* 5+1=stage2_64K_pages: 0x20000 - 0x7ffff */+1:+ pushw %ds+ popw %ax+ addw $0x1000, %ax+ pushw %ax+ popw %ds+ pushw %es+ popw %ax+ addw $0x1000, %ax+ pushw %ax+ popw %es+ movw $0x8000, %cx+ repz movsw+ decb %bl+ jnz 1b++ /* put the config file name */+ xorw %ax, %ax+ movw %ax, %es+ movw %ax, %ds+ movw %ax, %dx /* let DL=0 */+ xorl %ebp, %ebp+ + movw $0x0010, %cx /* set max length of grub version string */+ movw $0x8212, %di /* version string */+ cld+ /* AL is already 0. Locate the end of version string */+ repnz scasb /* find the location of the default config file name */+ jcxz 1f /* failed, will not use the default config file name */++ movw $0x4e, %cx /* max length of config file name */+ movw $(default_config_file + 0x8200 - pre_stage2_start), %si+ cld+ repz movsb /* move file name to the config-file field of stage2 */+1:+ sti++ movw $(launch_pre_stage2 + 0x8200 - pre_stage2_start), %si+ call print_message++//1: loop 1b /* should delay? */++ jmp pre_stage2_start //ljmp $0, $0x8200++launch_pre_stage2:+ .ascii "\r\n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -