diff --git a/AUTHORS b/AUTHORS index 300832d0c..202cd70a7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,7 +15,9 @@ OKUJI Yoshinori contributed many bugfixes and new features, such as working LBA support, /sbin/grub support for configuration files, the script /sbin/grub-install, the utility /bin/mbchk, the new engine for builtin commands, disk swapping support, keyboard configuration support, -network support, online help support, and command-line history support. +network support, online help support, command-line history support, +hidden menu support, the new Linux loader, serial terminal support, +single-line editing support, and several new commands. Peter Astrand added support for a color menu. @@ -30,3 +32,5 @@ Jochen Hoenicke rewrote stage2/fsys_fat.c and wrote stage2/fsys_reiserfs.c. Christoph Plattner added support for Net Boot Image Proposal. + +Stefan Ondrejicka added the commands "partnew" and "parttype". diff --git a/ChangeLog b/ChangeLog index 533a4a42a..ac230f425 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2000-09-30 OKUJI Yoshinori + + * stage2/fsys_reiserfs.c (reiserfs_mount): Check if the length + of the partition is less than the size of a super block, before + attempting to read the super block. + + * grub/asmstub.c (console_putchar) + [HAVE_LIBCURSES_H && REFRESH_IMMEDIATELY]: Call refresh, to ease + debugging. + +2000-09-30 OKUJI Yoshinori + + Added two new commands, "partnew" and "parttype", based on the + patch by Stefan Ondrejicka : + * stage2/builtins.c (partnew_func): New function. + (builtin_partnew): New variable. + (parttype_func): New function. + (builtin_parttype): New variable. + (builtin_table): Added pointers to BUILTIN_PARTNEW and to + BUILTIN_PARTTYPE. + 2000-09-29 OKUJI Yoshinori * stage2/builtins.c (find_func): New variable GOT_FILE is set to diff --git a/NEWS b/NEWS index affebe0d9..554ce5f4c 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,8 @@ New in 0.5.96 - XXXX-XX-XX: you specify the option `--prefix'. * The utility `grub-install' recognizes a separate boot partition automatically. +* New commands, "partnew" and "parttype". You can modify partition + tables with these commands. New in 0.5.95 - 2000-06-27: * NetBSD ELF kernel support is added. You have to specify the new option diff --git a/THANKS b/THANKS index 1a2e26576..4f5e558b4 100644 --- a/THANKS +++ b/THANKS @@ -44,6 +44,7 @@ Pavel Roskin Per Lundberg Peter Astrand Ramon van Handel +Stefan Ondrejicka Stephen Early Takehiro Suzuki Thierry DELHAISE diff --git a/grub/asmstub.c b/grub/asmstub.c index 937e51563..12cf45e0b 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -514,7 +514,12 @@ console_putchar (int c) move (y + 1, x); } else - addch (c); + { + addch (c); +#ifdef REFRESH_IMMEDIATELY + refresh (); +#endif + } } else #endif diff --git a/stage2/builtins.c b/stage2/builtins.c index 7a1a0ae21..52ce0bb14 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -2375,6 +2375,209 @@ static struct builtin builtin_modulenounzip = " disabled." }; + +/* partnew PART TYPE START LEN */ +static int +partnew_func (char *arg, int flags) +{ + int new_type, new_start, new_len; + int start_cl, start_ch, start_dh; + int end_cl, end_ch, end_dh; + int entry; + char *mbr = (char *) SCRATCHADDR; + + /* Convert a LBA address to a CHS address in the INT 13 format. */ + auto void lba_to_chs (int lba, int *cl, int *ch, int *dh); + void lba_to_chs (int lba, int *cl, int *ch, int *dh) + { + int cylinder, head, sector; + + sector = lba % buf_geom.sectors + 1; + head = (lba / buf_geom.sectors) % buf_geom.heads; + cylinder = lba / (buf_geom.sectors * buf_geom.heads); + + if (cylinder >= buf_geom.cylinders) + cylinder = buf_geom.cylinders - 1; + + *cl = sector | ((cylinder & 0x300) >> 2); + *ch = cylinder & 0xFF; + *dh = head; + } + + /* Get the drive and the partition. */ + if (! set_device (arg)) + return 1; + + /* The drive must be a hard disk. */ + if (! (current_drive & 0x80)) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* The partition must a primary partition. */ + if ((current_partition >> 16) > 3 + || (current_partition & 0xFFFF) != 0xFFFF) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + entry = current_partition >> 16; + + /* Get the new partition type. */ + arg = skip_to (0, arg); + if (! safe_parse_maxint (&arg, &new_type)) + return 1; + + /* The partition type is unsigned char. */ + if (new_type > 0xFF) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* Get the new partition start. */ + arg = skip_to (0, arg); + if (! safe_parse_maxint (&arg, &new_start)) + return 1; + + /* Get the new partition length. */ + arg = skip_to (0, arg); + if (! safe_parse_maxint (&arg, &new_len)) + return 1; + + /* Read the MBR. */ + if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr)) + return 1; + + /* Check if the new partition will fit in the disk. */ + if (new_start + new_len > buf_geom.total_sectors) + { + errnum = ERR_GEOM; + return 1; + } + + /* Store the partition information in the MBR. */ + lba_to_chs (new_start, &start_cl, &start_ch, &start_dh); + lba_to_chs (new_start + new_len - 1, &end_cl, &end_ch, &end_dh); + + PC_SLICE_FLAG (mbr, entry) = 0; + PC_SLICE_HEAD (mbr, entry) = start_dh; + PC_SLICE_SEC (mbr, entry) = start_cl; + PC_SLICE_CYL (mbr, entry) = start_ch; + PC_SLICE_TYPE (mbr, entry) = new_type; + PC_SLICE_EHEAD (mbr, entry) = end_dh; + PC_SLICE_ESEC (mbr, entry) = end_cl; + PC_SLICE_ECYL (mbr, entry) = end_ch; + PC_SLICE_START (mbr, entry) = new_start; + PC_SLICE_LENGTH (mbr, entry) = new_len; + + /* Make sure that the MBR has a valid signature. */ + PC_MBR_SIG (mbr) = PC_MBR_SIGNATURE; + + /* Write back the MBR to the disk. */ + buf_track = -1; + if (biosdisk (BIOSDISK_WRITE, current_drive, &buf_geom, 0, 1, SCRATCHSEG)) + { + errnum = ERR_WRITE; + return 1; + } + + return 0; +} + +static struct builtin builtin_partnew = +{ + "partnew", + partnew_func, + BUILTIN_CMDLINE | BUILTIN_MENU, + "partnew PART TYPE START LEN", + "Create a primary partition at the starting address START with the" + " length LEN, with the type TYPE. START and LEN are in sector units." +}; + + +/* parttype PART TYPE */ +static int +parttype_func (char *arg, int flags) +{ + int new_type; + unsigned long part = 0xFFFFFF; + unsigned long start, len, offset, ext_offset; + int entry, type; + char *mbr = (char *) SCRATCHADDR; + + /* Get the drive and the partition. */ + if (! set_device (arg)) + return 1; + + /* The drive must be a hard disk. */ + if (! (current_drive & 0x80)) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* The partition must be a PC slice. */ + if ((current_partition >> 16) == 0xFF + || (current_partition & 0xFFFF) != 0xFFFF) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* Get the new partition type. */ + arg = skip_to (0, arg); + if (! safe_parse_maxint (&arg, &new_type)) + return 1; + + /* The partition type is unsigned char. */ + if (new_type > 0xFF) + { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + /* Look for the partition. */ + while (next_partition (current_drive, 0xFFFFFF, &part, &type, + &start, &len, &offset, &entry, + &ext_offset, mbr)) + { + if (part == current_partition) + { + /* Found. */ + + /* Set the type to NEW_TYPE. */ + PC_SLICE_TYPE (mbr, entry) = new_type; + + /* Write back the MBR to the disk. */ + buf_track = -1; + if (biosdisk (BIOSDISK_WRITE, current_drive, &buf_geom, + offset, 1, SCRATCHSEG)) + { + errnum = ERR_WRITE; + return 1; + } + + /* Succeed. */ + return 0; + } + } + + /* The partition was not found. ERRNUM was set by next_partition. */ + return 1; +} + +static struct builtin builtin_parttype = +{ + "parttype", + parttype_func, + BUILTIN_CMDLINE | BUILTIN_MENU, + "parttype PART TYPE", + "Change the type of the partition PART to TYPE." +}; + /* password */ static int @@ -3778,6 +3981,8 @@ struct builtin *builtin_table[] = &builtin_map, &builtin_module, &builtin_modulenounzip, + &builtin_partnew, + &builtin_parttype, &builtin_password, &builtin_pause, #ifdef GRUB_UTIL diff --git a/stage2/fsys_reiserfs.c b/stage2/fsys_reiserfs.c index 8cf7a1848..1caf01cc3 100644 --- a/stage2/fsys_reiserfs.c +++ b/stage2/fsys_reiserfs.c @@ -560,7 +560,8 @@ reiserfs_mount (void) struct reiserfs_super_block super; int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; - if (! devread (superblock, 0, sizeof (struct reiserfs_super_block), + if (part_length < sizeof (struct reiserfs_super_block) + || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), (char *) &super) || (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0 && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0) @@ -570,8 +571,9 @@ reiserfs_mount (void) { /* Try old super block position */ superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS; - if (! devread (superblock, 0, sizeof (struct reiserfs_super_block), - (char *) &super)) + if (part_length < sizeof (struct reiserfs_super_block) + || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), + (char *) &super)) return 0; if (substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0