Date: Thu, 31 Aug 2000 08:29:16 -0500 (CDT) From: Mike Meyer <mwm@mired.org> To: R Joseph Wright <rjoseph@mammalia.org> Cc: questions@freebsd.org, zzhang@cs.binghamton.edu Subject: Re: boot manager other than booteasy Message-ID: <14766.23980.183756.126206@guru.mired.org> In-Reply-To: <115781327@toto.iv>
next in thread | previous in thread | raw e-mail | index | archive | help
R Joseph Wright writes: > And Siegbert Baude spoke: > > Zhihui Zhang wrote: > > > I have installed Linux on my laptop and am using LILO as the boot manager. > > > Compared to booteasy, LILO can not remember the last OS I booted from and > > > boot from that OS automatically next time powerup. But booteasy can not > > > recognize Linux in a DOS extended partition. Is there any FREE boot > > > manager that can boot Linux in a DOS extended partition and yet can > > > remember the last OS it booted from? > That looks very slick and all, but I recommend grub, now in the ports > collection (sysutils/grub). It will boot virtually anything and can be used > interactively on its own command line. It also does not need Lilo to boot > into Linux. > > However, I don't know if it will remember the last OS booted > from and boot from it. No, it can't. The following patch fixes that. It adds the command "savedefault", which saves the current entry number when used in an entry, and makes the "default" command accept the keyword "saved", which uses the value from the last saved default. Grub is much more flexible than booteasy in general, as it boots "entries" as opposed to partitions, so you can have a menu that boots the same OS in various modes. This patch carries that on, allowing some entries to become the default, and not others. Feedback on it would be greatly appreciated. <mike diff -ru grub-0.5.95-orig/docs/user-ref.texi grub-0.5.95/docs/user-ref.texi --- grub-0.5.95-orig/docs/user-ref.texi Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/docs/user-ref.texi Sun Aug 27 05:46:10 2000 @@ -474,7 +474,7 @@ Commands usable in the menu only. -@deffn Command default num +@deffn Command default [num | `saved'] Set the default entry to the entry number @var{num} (if not specified, it is 0, the first entry). @end deffn diff -ru grub-0.5.95-orig/grub/asmstub.c grub-0.5.95/grub/asmstub.c --- grub-0.5.95-orig/grub/asmstub.c Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/grub/asmstub.c Sun Aug 27 05:46:10 2000 @@ -85,6 +85,7 @@ unsigned long install_partition = 0x20000; unsigned long boot_drive = 0; +unsigned long stage2_sector2 = 0; char version_string[] = VERSION; char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */ diff -ru grub-0.5.95-orig/stage2/asm.S grub-0.5.95/stage2/asm.S --- grub-0.5.95-orig/stage2/asm.S Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/stage2/asm.S Sun Aug 27 06:31:30 2000 @@ -73,6 +73,8 @@ .long 0xFFFFFF VARIABLE(stage2_id) .byte STAGE2_ID +VARIABLE(saved_entry) + .byte 1 VARIABLE(force_lba) .byte 0 VARIABLE(version_string) @@ -112,6 +114,9 @@ ADDR32 movb %dl, EXT_C(boot_drive) #endif + /* save the second sector address for savedefault */ + ADDR32 movl %ecx,EXT_C(stage2_sector2) + /* reset disk system (%ah = 0) */ int $0x13 @@ -2095,6 +2100,10 @@ #else .long 0 #endif + +/* sector # for stage 2, sector 2 for savedefault */ +VARIABLE(stage2_sector2) + .long 0 /* an address can only be long-jumped to if it is in memory, this is used by multiple routines */ diff -ru grub-0.5.95-orig/stage2/builtins.c grub-0.5.95/stage2/builtins.c --- grub-0.5.95-orig/stage2/builtins.c Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/stage2/builtins.c Sun Aug 27 07:04:01 2000 @@ -697,6 +697,27 @@ static int default_func (char *arg, int flags) { + if (grub_strcmp (arg, "saved") == 0) + { + struct geometry geom ; + /* Setup */ + if (get_diskinfo(boot_drive, &geom)) + { + errnum = ERR_NO_DISK; + return 1; + } + /* Get original sector 2 from the disk */ + if (biosdisk (BIOSDISK_READ, boot_drive, &geom, + stage2_sector2, 1, SCRATCHSEG)) + { + errnum = ERR_READ; + return 1; + } + + default_entry = ((unsigned char *) SCRATCHADDR)[STAGE2_SAVED_DEFAULT]; + return 0; + } + if (! safe_parse_maxint (&arg, &default_entry)) return 1; @@ -709,9 +730,9 @@ default_func, BUILTIN_MENU, #if 0 - "default NUM", - "Set the default entry to entry number NUM (if not specified, it is" - " 0, the first entry)." + "default [NUM | `saved']", + "Set the default entry to entry number NUM or to the value saved by" + " `savedefault' (if not specified, it is 0, the first entry)." #endif }; @@ -1994,6 +2015,57 @@ }; +/* savedefault */ +static int +savedefault_func (char *arg, int flags) +{ + struct geometry geom ; + + /* Setup */ + if (get_diskinfo(boot_drive, &geom)) + { + errnum = ERR_NO_DISK; + return 1; + } + + /* Get original sector 2 from the disk */ + if (biosdisk (BIOSDISK_READ, boot_drive, &geom, + stage2_sector2, 1, SCRATCHSEG)) + { + errnum = ERR_READ; + return 1; + } + + if ( *((unsigned char *) (SCRATCHADDR + STAGE2_SAVED_DEFAULT)) + != current_entry_number ) + { + + /* Set the entry number */ + *((unsigned char *) (SCRATCHADDR + STAGE2_SAVED_DEFAULT)) + = current_entry_number; + + /* Now flush the block back to disk */ + if (biosdisk (BIOSDISK_WRITE, boot_drive, &geom, + stage2_sector2, 1, SCRATCHSEG)) + { + errnum = ERR_WRITE; + return 1; + } + } + + return 0; +} + +static struct builtin builtin_savedefault = +{ + "savedefault", + savedefault_func, + BUILTIN_CMDLINE, + "savedefault", + "Set the saved default entry to the current entry." + " This is will make \"default saved\" use the current entry." +}; + /* map */ /* Map FROM_DRIVE to TO_DRIVE. */ static int @@ -3103,6 +3175,7 @@ &builtin_read, &builtin_root, &builtin_rootnoverify, + &builtin_savedefault, &builtin_setkey, &builtin_setup, &builtin_testload, diff -ru grub-0.5.95-orig/stage2/shared.h grub-0.5.95/stage2/shared.h --- grub-0.5.95-orig/stage2/shared.h Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/stage2/shared.h Sun Aug 27 06:14:33 2000 @@ -196,7 +196,8 @@ #define STAGE2_INSTALLPART 0x8 #define STAGE2_STAGE2_ID 0xc #define STAGE2_FORCE_LBA 0xd -#define STAGE2_VER_STR_OFFS 0xe +#define STAGE2_SAVED_DEFAULT 0xe +#define STAGE2_VER_STR_OFFS 0xf /* Stage 2 identifiers */ #define STAGE2_ID_STAGE2 0 @@ -424,6 +425,7 @@ extern unsigned long install_partition; extern unsigned long boot_drive; +extern unsigned long stage2_sector2; extern unsigned long boot_part_addr; extern unsigned long boot_part_offset; extern unsigned char force_lba; @@ -461,6 +463,7 @@ /* GUI interface variables. */ extern int fallback_entry; extern int default_entry; +extern int current_entry_number ; extern char *password; extern int auth; extern char commands[]; diff -ru grub-0.5.95-orig/stage2/stage2.c grub-0.5.95/stage2/stage2.c --- grub-0.5.95-orig/stage2/stage2.c Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/stage2/stage2.c Sun Aug 27 05:46:10 2000 @@ -168,6 +168,7 @@ #endif } +int current_entry_number; /* For savedefault */ static void run_menu (char *menu_entries, char *config_entries, int num_entries, char *heap, int entryno) @@ -524,6 +525,7 @@ { cls (); + current_entry_number = entryno ; /* For savedefault */ if (config_entries) printf (" Booting \'%s\'\n\n", get_entry (menu_entries, first_entry + entryno, 0)); diff -ru grub-0.5.95-orig/stage2/start.S grub-0.5.95/stage2/start.S --- grub-0.5.95-orig/stage2/start.S Sun Aug 27 05:45:27 2000 +++ grub-0.5.95/stage2/start.S Sun Aug 27 06:31:27 2000 @@ -73,7 +73,12 @@ /* this sets up for the first run through "bootloop" */ movw $ABS(firstlist - BOOTSEC_LISTSIZE), %di - + + /* Save the second sector # for setdefault */ + movl (%di),%eax + popw %dx + pushl %eax + pushw %dx /* this is the loop for reading the secondary boot-loader in */ bootloop: @@ -313,6 +318,7 @@ bootit: popw %dx /* this makes sure %dl is our "boot" drive */ + popl %ecx /* Pass the stage2 second sector address on as well */ #ifdef STAGE1_5 ljmp $0, $0x2200 #else /* ! STAGE1_5 */ @@ -371,6 +377,7 @@ cmpb $0, %al jne 1b /* if not end of string, jmp to display */ ret + lastlist: /* To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?14766.23980.183756.126206>