From 98fb5cb9a46c0c4ff854649bc2a4a594bd4b4f0e Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 18 Jun 2007 15:47:26 +0200 Subject: applied save-default-entry-on-mbr.diff --- stage2/builtins.c | 2 + stage2/disk_io.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stage2/shared.h | 5 ++++ stage2/stage2.c | 3 ++ 4 files changed, 64 insertions(+), 0 deletions(-) diff --git a/stage2/builtins.c b/stage2/builtins.c index 535c713..7fe6cc6 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -3343,6 +3343,8 @@ savedefault_func (char *arg, int flags) /* Clear the cache. */ buf_track = -1; } + else + put_new_entryno_to_mbr(tmp_drive, entryno); fail: saved_drive = tmp_drive; diff --git a/stage2/disk_io.c b/stage2/disk_io.c index b9bc526..5b88e8c 100644 --- a/stage2/disk_io.c +++ b/stage2/disk_io.c @@ -1788,3 +1788,57 @@ grub_close (void) if (fsys_table[fsys_type].close_func != 0) (*(fsys_table[fsys_type].close_func)) (); } + +#ifndef STAGE1_5 +int +read_entryno_from_mbr(int drive, char *sector) +{ + /* drive must be a hard disk and stage1_5 must be right after the MBR */ + if (!(drive & 0x80)) + return 0; + if (!rawread(drive, 2, 0, SECTOR_SIZE, sector)) + return 0; + /* sanity checks */ + if (sector[STAGE2_VER_MAJ_OFFS] != COMPAT_VERSION_MAJOR || + sector[STAGE2_VER_MAJ_OFFS+1] != COMPAT_VERSION_MINOR || + *(unsigned *)§or[STAGE2_INSTALLPART] != 0xFFFFFF || + grub_memcmp(§or[STAGE2_VER_STR_OFFS], version_string, + sizeof(VERSION))) { +#if 0 + printf("read: sec=%d %d %d %s=%s(%d)\n", + sector[STAGE2_VER_MAJ_OFFS], sector[STAGE2_VER_MAJ_OFFS+1], + sector[STAGE2_INSTALLPART], §or[STAGE2_VER_STR_OFFS], + version_string, sizeof(VERSION)); +#endif + return 0; + } + return 1; +} + +/* Get saved_entryno from the MBR */ +void +get_saved_entryno_from_mbr(int drive) +{ + char sector[SECTOR_SIZE]; + + errnum = ERR_NONE; + if (!read_entryno_from_mbr(drive, sector)) + return 0; + /* get it from the saved_entryno place */ + saved_entryno = *(unsigned*)§or[STAGE2_SAVED_ENTRYNO]; +} + +/* Put entryno into the MBR. Returns 1 if done, otherwise 0 (error...) */ +int +put_new_entryno_to_mbr(int drive, unsigned entryno) +{ + char sector[SECTOR_SIZE]; + + errnum = ERR_NONE; + if (!read_entryno_from_mbr(saved_drive, sector)) + return 0; + *(unsigned *)§or[STAGE2_SAVED_ENTRYNO] = entryno; + rawwrite (drive, 2, sector); + return !errnum; +} +#endif /* STAGE1_5 */ diff --git a/stage2/shared.h b/stage2/shared.h index 77eef11..f01d6ee 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -956,6 +956,11 @@ int grub_seek (int offset); /* Close a file. */ void grub_close (void); +#ifndef STAGE1_5 +void get_saved_entryno_from_mbr(int drive); +int put_new_entryno_to_mbr(int drive, unsigned entryno); +#endif + /* List the contents of the directory that was opened with GRUB_OPEN, printing all completions. */ int dir (char *dirname); diff --git a/stage2/stage2.c b/stage2/stage2.c index 96e18cd..a93a630 100644 --- a/stage2/stage2.c +++ b/stage2/stage2.c @@ -896,6 +896,9 @@ cmain (void) grub_close (); } + else + get_saved_entryno_from_mbr(saved_drive); + errnum = ERR_NONE; do -- 1.4.4.3