📄 grldrstart.s
字号:
#;// booted from no-emulation-mode bootable CDROM #;movb $0xff, %dh // partition 0xff means whole drive(for CDROM) #; #; if needed, 0xfe can be used as an indicator #; #; here for the bootable CDROM and changed to #; #; 0xff later. #;1: #; #;//if not booted from CDROM, don't touch the boot partition number(dh) cli xorw %ax, %ax movw %ax, %ss movw $0x0400, %sp /* tmp use real-mode IDT as stack */ movw %cs, %bp /* save CS to BP */ call 1f1: popw %bx /* BX=Instruction Pointer of 1b */ subw $(1b - _start1), %bx movw %bx, %cx shrw $4, %bx addw %bp, %bx pushw %bx /* new CS */ andw $0x000f, %cx addw $(1f - _start1), %cx pushw %cx /* new IP */ lret1: pushw %cs popw %ds /* CS=DS=BX, CS:0000 = _start1 */ addw $((pre_stage2_start - _start1) >> 4), %bx /* BX:0000 = pre_stage2_start */ cmpw $0x820, %bx jb 2f movw $((0x8200 - (pre_stage2_start - _start1) - 0x400) >> 4), %cx /* Now CS(=DS) >= CX+0x40 */ movw %cx, %es xorw %di, %di xorw %si, %si ///////////////////////////////////////////////////////////// // // CS // DS 0x820 BX // _start1---------------pre_stage2_start // CX+0x40---------------0x820 // CX // ES // ///////////////////////////////////////////////////////////// movw $0x200, %cx /* move 2 sectors */ cld repz movsw pushw %es /* ES:0000 = _start */ pushw $(1f - _start) lret /* CS=ES, CS:0000 = _start1 */1: /* move BX:0000 to 0820:0000 upward since BX >= 0x820 */ cld movw %bx, %ds movw $0x820, %bx movw %bx, %es xorw %si, %si xorw %di, %di movw $6, %bx /* 64K pages: 0x20000 - 0x7ffff */1: movw $0x8000, %cx repz movsw movw %ds, %ax addw $0x1000, %ax movw %ax, %ds movw %es, %ax addw $0x1000, %ax movw %ax, %es decw %bx jnz 1b jmp 3f2: /* move BX:0000 to 0820:0000 downward since BX < 0x820 */ std addw $0x7000, %bx movw %bx, %ds movw $0x7820, %bx movw %bx, %es movw $0xfffe, %si movw %si, %di movw $8, %bx /* 64K pages: 0x08200 - 0x881ff */1: movw $0x8000, %cx repz movsw movw %ds, %ax subw $0x1000, %ax movw %ax, %ds movw %es, %ax subw $0x1000, %ax movw %ax, %es decw %bx jnz 1b cld3: /* put the config file name */ xorw %ax, %ax movw %ax, %es movw %ax, %ds xorl %ebp, %ebp movb %dh, 0x820A /* this is the boot partition number */ #; clear saved_entryno so that force_cdrom_as_boot_device be cleared #; later in common.c movl %ebp, 0x820C /* EBP=0, clear saved_entryno */ 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 %cs, %si /* CS:0000 = _start1 */ shlw $4, %si /* 0000:SI = _start1 */ addw $(default_config_file - _start1), %si //movw $(default_config_file + 0x8200 - pre_stage2_start), %si cld repz movsb /* move file name to the config-file field of stage2 */1: movw $0x0003, %ax /* set display mode: 80*25 color text */ int $0x10 xorw %bx, %bx movw $(launch_pre_stage2 - _start1), %si call print_message /* CS:SI points to message string */ xorw %ax, %ax movw %ax, %ss movw $0x2000, %sp sti ljmp $0, $0x8200launch_pre_stage2: .ascii "\r\n\r\nBooting GRLDR...\r\n" .byte 0 /* mark the end of ascii zero string */default_config_file://#ifndef PRESET_MENU_STRING .ascii "/menu.lst"//#else// .ascii "[default menu is disabled]"//#endif .byte 0 /* mark the end of ascii zero string */#endif /* ! defined(GRLDR_MBR) && (! defined(GRLDR_INSTALL)) */ . = _start1 + 0x400#define ALTERNATIVE_KERNEL/* * The following is based on FreeDOS, modified heavily by Tinybit in Feb, 2004 * * Merges LBA and CHS boot sectors to ONE FAT32 boot sector! * * Memory layout for GRLDR FAT32 single stage boot process: * * ... * |-------| 1FE0:7E00 * |BOOTSEC| (GRUB does not use this relocation area) * |RELOC. | (overwritten by kernel loaded) * |-------| 1FE0:7C00 * ... * |-------| * |KERNEL | (overwrites bootsec reloc.) * |LOADED | (holds 1 sector directory buffer before kernel load) * |-------| 2000:0000 * ... * |-------| 0000:7E00 * |BOOTSEC| GRUB always run inside this sector, * |ORIGIN | no relocation. * |-------| 0000:7C00 * ... * |-------| 0060:0200 * | FAT | (only 1 sector buffered) * |-------| 0060:0000 * ... * *//*; This is an LBA-enabled FreeDOS FAT32 boot sector (single sector!).; You can use and copy source code and binaries under the terms of the; GNU Public License (GPL), version 2 or newer. See www.gnu.org for more.; Based on earlier work by FreeDOS kernel hackers, modified heavily by; Eric Auer and Jon Gentle in 7 / 2003.;; Features: Uses LBA and calculates all variables from BPB/EBPB data,; thus making partition move / resize / image-restore easier. FreeDOS; can boot from FAT32 partitions which start > 8 GB boundary with this; boot sector. Disk geometry knowledge is not needed for booting.;; Windows uses 2-3 sectors for booting (sector stage, statistics sector,; filesystem stage). Only using 1 sector for FreeDOS makes multi-booting; of FreeDOS and Windows on the same filesystem easier.;; Requirements: LBA BIOS and 386 or better CPU. Use the older CHS-only; boot sector if you want FAT32 on really old PCs (problems: you cannot; boot from > 8 GB boundary, cannot move / resize / ... without applying; SYS again if you use the CHS-only FAT32 boot sector).;; FAT12 / FAT16 hints: Use the older CHS-only boot sector unless you; have to boot from > 8 GB. The LBA-and-CHS FAT12 / FAT16 boot sector; needs applying SYS again after move / resize / ... a variant of that; boot sector without CHS support but with better move / resize / ...; support would be good for use on LBA harddisks.; Memory layout for the FreeDOS FAT32 single stage boot process:; ...; |-------| 1FE0:7E00; |BOOTSEC|; |RELOC. |; |-------| 1FE0:7C00; ...; |-------| 2000:0200; | FAT | (only 1 sector buffered); |-------| 2000:0000; ...; |-------| 0000:7E00; |BOOTSEC| overwritten by the kernel, so the; |ORIGIN | bootsector relocates itself up...; |-------| 0000:7C00; ...; |-------|; |KERNEL | maximum size 134k (overwrites bootsec origin); |LOADED | (holds 1 sector directory buffer before kernel load); |-------| 0060:0000; ...*/#define BOOTGRUB /* undef this if compiled for loading FreeDOS *///#undef BOOTGRUB#ifdef BOOTGRUB#define LOADSEG 0x2000#define FATSEG 0x0060#else#define LOADSEG 0x0060#define FATSEG 0x2000#endifEntry_32: jmp 1f . = Entry_32 + 0x02 /* The default mode is CHS. This is for maximum compatiblity with * small-sized disks, e.g., floppies. * * Valid values are 0x90 for CHS mode, or 0x0e for LBA mode. * * If the BIOS int13 supports LBA, this byte can be safely set to 0x0e. * * Some USB BIOSes might have bugs when using CHS mode, so the format * program should set this byte to 0x0e. It seems that (generally) all * USB BIOSes have LBA support. * * If the format program does not know whether the BIOS has LBA * support, it may operate this way: * * if (partition_start + total_sectors_in_partition) exceeds the CHS * addressing ability(especially when it is greater than 1024*256*63), * the caller should set this byte to 0x0e, otherwise, set to 0x90. */ .byte 0x90 /* for CHS. Another possible value is 0x0e for LBA */ . = Entry_32 + 0x03#ifdef BOOTGRUB .ascii "GRLDR " /* OEM name string (of OS which formatted the disk). */#endif . = Entry_32 + 0x0b .word 0x200 /* bytes per sector. Must be 512 */ . = Entry_32 + 0x0d /* Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64 and 128. * But a cluster size larger than 32K should not occur. */ .byte 1 /* sectors per cluster */ . = Entry_32 + 0x0e /* Reserved sectors(number of sectors before the first FAT, * including the boot sector), usually 1. */ .word 1 /* reserved sectors */ . = Entry_32 + 0x10 /* Number of FATs(nearly always 2). */ .byte 2 /* number of FATs */ . = Entry_32 + 0x11 /* (Maximum number of root directory entries)Must be 0. */ .word 0 /* Max dir entries for FAT12/FAT16 */ . = Entry_32 + 0x13 /* (Total number of sectors for small disks only)Must be 0. */ .word 0 /* total sectors for FAT12/FAT16 */ . = Entry_32 + 0x15 /* Media descriptor byte, pretty meaningless now. */ .byte 0xf8 /* media descriptor */ . = Entry_32 + 0x16 /* (Sectors per FAT)Must be 0. */ .word 0 /* sectors per FAT for FAT12/FAT16 */ . = Entry_32 + 0x18 .word 18 /* sectors per track */ . = Entry_32 + 0x1a .word 2 /* number of heads */ . = Entry_32 + 0x1c /* Number of hidden sectors (those preceding the boot sector). * Also referred to as the starting sector of the partition. * For floppies, it should be 0. */ .long 0 /* hidden sectors */ . = Entry_32 + 0x20 /* Total number of sectors in the filesystem. */ .long 0 /* total sectors for FAT32 */ . = Entry_32 + 0x24 /* FAT32 sectors per FAT. */ .long 0 . = Entry_32 + 0x28 /* If bit 7 is clear then all FATs are updated, otherwise bits 0-3 * give the current active FAT, all other bits are reserved. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x2a /* High byte is major revision number, low byte is minor revision * number, currently both are 0. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x2c /* Root directory starting cluster. */ .long 0 . = Entry_32 + 0x30 /* File system information sector number. * This word is not used by grldr boot code. */ .word 0 . = Entry_32 + 0x32 /* If non-zero this gives the sector which holds a copy of the * boot record, usually 6. * This word is not used by grldr boot code. */ .word 6 . = Entry_32 + 0x34 /* Reserved, 12 bytes, set to 0. */ .long 0 .long 0 .long 0 . = Entry_32 + 0x40 /* drive number of the boot device. * This byte is ignored for read. The program will write DL onto * this byte. The caller should set drive number in DL. * We assume all BIOSes pass correct drive number in DL. * That is to say, buggy BIOSes are not supported!! */ .byte 0 . = Entry_32 + 0x41 /* partition number of this filesystem in the boot drive. * This byte is ignored for read. The boot code will write partition * number onto this byte. See Entry + 0x5d below. */ .byte 0 . = Entry_32 + 0x42 /* Signature (must be 28h or 29h to be recognised by NT). */ .byte 0x29 /* extended boot signature for FAT12/FAT16 */ . = Entry_32 + 0x43 .long 0x0AC4AF63 /* volume serial number */ . = Entry_32 + 0x47 .ascii "NO NAME " /* volume label, 11 bytes. */ . = Entry_32 + 0x52 .ascii "FAT32 " /* filesystem ID, 8 bytes. *//*; bp is initialized to 7c00h; %define bsOemName bp+0x03 ; OEM label (8)%define bsBytesPerSec bp+0x0b ; bytes/sector (dw)%define bsSecPerClust bp+0x0d ; sectors/allocation unit (db)%define bsResSectors bp+0x0e ; # reserved sectors (dw)%define bsFATs bp+0x10 ; # of fats (db); %define bsRootDirEnts bp+0x11 ; # of root dir entries (dw, 0 for FAT32) ; (FAT32 has root dir in a cluster chain); %define bsSectors bp+0x13 ; # sectors total in image (dw, 0 for FAT32) ; (if 0 use nSectorHuge even if FAT16); %define bsMedia bp+0x15 ; media descriptor: fd=2side9sec, etc... (db); %define sectPerFat bp+0x16 ; # sectors in a fat (dw, 0 for FAT32) ; (FAT32 always uses xsectPerFat)%define sectPerTrack bp+0x18 ; # sectors/track; %define nHeads bp+0x1a ; # heads (dw)%define nHidden bp+0x1c ; # hidden sectors (dd); %define nSectorHuge bp+0x20 ; # sectors if > 65536 (dd)%define xsectPerFat bp+0x24 ; Sectors/Fat (dd) ; +0x28 dw flags (for fat mirroring) ; +0x2a dw filesystem version (usually 0)%define xrootClst bp+0x2c ; Starting cluster of root directory (dd) ; +0x30 dw -1 or sector number of fs.-info sector ; +0x32 dw -1 or sector number of boot sector backup ; (+0x34 .. +0x3f reserved)%define drive bp+0x40 ; Drive number bp+0x41 ; partition number for GRLDR%define fat_sector bp+0x44 ; last accessed FAT sector (dd) ; (overwriting unused bytes)%define fat_start bp+0x48 ; first FAT sector (dd) ; (overwriting unused bytes)%define data_start bp+0x4c ; first data sector (dd) ; (overwriting unused bytes)*/ /* not used: [0x42] = byte 0x29 (ext boot param flag) * [0x43] = dword serial * [0x47] = label (padded with 00, 11 bytes) * [0x52] = "FAT32",32,32,32 (not used by Windows) * ([0x5a] is where FreeDOS parts start) */ . = Entry_32 + 0x5a1: cli cld#ifdef BOOTGRUB . = Entry_32 + 0x5c /* the byte at offset 0x5d stores the real partition number for read. * the format program or the caller should set it to a correct value. * For floppies, it should be 0xff, which stands for whole drive. */ movb $0xff, %dh /* boot partition number */ cmpb $0xff, %dh /* is floppy? */ jne 1f movb $0, %dl /* yes, let drive number = 0 */1:#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -