1 /* disk_io.c - implement abstract BIOS disk input and output */ 2 /* 3 * GRUB -- GRand Unified Bootloader 4 * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. 5 * Copyright 2021 RackTop Systems, Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 23 #include <shared.h> 24 #include <filesys.h> 25 #include <gpt.h> 26 27 #ifdef SUPPORT_NETBOOT 28 # include <grub.h> 29 #endif 30 31 #ifdef GRUB_UTIL 32 # include <device.h> 33 #endif 34 35 /* instrumentation variables */ 36 void (*disk_read_hook) (unsigned long long, int, int) = NULL; 37 void (*disk_read_func) (unsigned long long, int, int) = NULL; 38 39 #ifndef STAGE1_5 40 int print_possibilities; 41 42 static int do_completion; 43 static int unique; 44 static char *unique_string; 45 46 #endif 47 48 int fsmax; 49 struct fsys_entry fsys_table[NUM_FSYS + 1] = 50 { 51 /* TFTP should come first because others don't handle net device. */ 52 # ifdef FSYS_TFTP 53 {"tftp", tftp_mount, tftp_read, tftp_dir, tftp_close, 0}, 54 # endif 55 # ifdef FSYS_FAT 56 {"fat", fat_mount, fat_read, fat_dir, 0, 0}, 57 # endif 58 # ifdef FSYS_EXT2FS 59 {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0}, 60 # endif 61 # ifdef FSYS_MINIX 62 {"minix", minix_mount, minix_read, minix_dir, 0, 0}, 63 # endif 64 # ifdef FSYS_REISERFS 65 {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed}, 66 # endif 67 # ifdef FSYS_VSTAFS 68 {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0}, 69 # endif 70 # ifdef FSYS_JFS 71 {"jfs", jfs_mount, jfs_read, jfs_dir, 0, jfs_embed}, 72 # endif 73 # ifdef FSYS_XFS 74 {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0}, 75 # endif 76 # ifdef FSYS_UFS 77 {"ufs", ufs_mount, ufs_read, ufs_dir, 0, ufs_embed}, 78 # endif 79 # ifdef FSYS_UFS2 80 {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed}, 81 # endif 82 # ifdef FSYS_ZFS 83 {"zfs", zfs_mount, zfs_read, zfs_open, 0, zfs_embed}, 84 # endif 85 # ifdef FSYS_ISO9660 86 {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0}, 87 # endif 88 /* XX FFS should come last as it's superblock is commonly crossing tracks 89 on floppies from track 1 to 2, while others only use 1. */ 90 # ifdef FSYS_FFS 91 {"ffs", ffs_mount, ffs_read, ffs_dir, 0, ffs_embed}, 92 # endif 93 {0, 0, 0, 0, 0, 0} 94 }; 95 96 97 /* These have the same format as "boot_drive" and "install_partition", but 98 are meant to be working values. */ 99 unsigned long current_drive = GRUB_INVALID_DRIVE; 100 unsigned long current_partition; 101 102 #ifndef STAGE1_5 103 /* The register ESI should contain the address of the partition to be 104 used for loading a chain-loader when chain-loading the loader. */ 105 unsigned long boot_part_addr = 0; 106 #endif 107 108 /* 109 * Global variables describing details of the filesystem 110 */ 111 112 /* FIXME: BSD evil hack */ 113 #include "freebsd.h" 114 int bsd_evil_hack; 115 116 /* filesystem type */ 117 int fsys_type = NUM_FSYS; 118 #ifndef NO_BLOCK_FILES 119 static int block_file = 0; 120 #endif /* NO_BLOCK_FILES */ 121 122 /* these are the translated numbers for the open partition */ 123 unsigned long long part_start; 124 unsigned long long part_length; 125 126 int current_slice; 127 128 /* ZFS root filesystem for booting */ 129 char current_rootpool[MAXNAMELEN]; 130 char current_bootfs[MAXNAMELEN]; 131 uint64_t current_bootfs_obj; 132 char current_bootpath[MAXPATHLEN]; 133 char current_devid[MAXPATHLEN]; 134 uint64_t current_bootguid; 135 uint64_t current_bootvdev; 136 int is_zfs_mount; 137 unsigned long best_drive; 138 unsigned long best_part; 139 int find_best_root; 140 141 /* disk buffer parameters */ 142 int buf_drive = -1; 143 unsigned long long buf_track; 144 struct geometry buf_geom; 145 146 /* filesystem common variables */ 147 int filepos; 148 int filemax; 149 150 static inline unsigned long 151 grub_log2 (unsigned long word) 152 { 153 asm volatile ("bsfl %1,%0" 154 : "=r" (word) 155 : "r" (word)); 156 return word; 157 } 158 #define log2 grub_log2 159 160 int 161 rawread(int drive, unsigned long long sector, int byte_offset, int byte_len, 162 char *buf) 163 { 164 int slen, sectors_per_vtrack; 165 int sector_size_bits = log2 (buf_geom.sector_size); 166 167 if (byte_len <= 0) 168 return 1; 169 170 while (byte_len > 0 && !errnum) 171 { 172 int soff, num_sect, size = byte_len; 173 unsigned long long track; 174 char *bufaddr; 175 176 /* 177 * Check track buffer. If it isn't valid or it is from the 178 * wrong disk, then reset the disk geometry. 179 */ 180 if (buf_drive != drive) 181 { 182 if (get_diskinfo (drive, &buf_geom)) 183 { 184 errnum = ERR_NO_DISK; 185 return 0; 186 } 187 buf_drive = drive; 188 buf_track = BUF_CACHE_INVALID; 189 sector_size_bits = log2 (buf_geom.sector_size); 190 } 191 192 slen = ((byte_offset + byte_len + buf_geom.sector_size - 1) 193 >> sector_size_bits); 194 195 /* Eliminate a buffer overflow. */ 196 if ((buf_geom.sectors << sector_size_bits) > BUFFERLEN) 197 sectors_per_vtrack = (BUFFERLEN >> sector_size_bits); 198 else 199 sectors_per_vtrack = buf_geom.sectors; 200 201 /* Get the first sector of track. */ 202 soff = sector % sectors_per_vtrack; 203 track = sector - soff; 204 num_sect = sectors_per_vtrack - soff; 205 bufaddr = ((char *) BUFFERADDR 206 + (soff << sector_size_bits) + byte_offset); 207 208 if (track != buf_track) 209 { 210 int bios_err, read_len = sectors_per_vtrack; 211 unsigned long long read_start = track; 212 213 /* 214 * If there's more than one read in this entire loop, then 215 * only make the earlier reads for the portion needed. This 216 * saves filling the buffer with data that won't be used! 217 */ 218 if (slen > num_sect) 219 { 220 read_start = sector; 221 read_len = num_sect; 222 bufaddr = (char *) BUFFERADDR + byte_offset; 223 } 224 225 bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom, 226 read_start, read_len, BUFFERSEG); 227 if (bios_err) 228 { 229 buf_track = BUF_CACHE_INVALID; 230 231 if (bios_err == BIOSDISK_ERROR_GEOMETRY) 232 errnum = ERR_GEOM; 233 else 234 { 235 /* 236 * If there was an error, try to load only the 237 * required sector(s) rather than failing completely. 238 */ 239 if (slen > num_sect 240 || biosdisk (BIOSDISK_READ, drive, &buf_geom, 241 sector, slen, BUFFERSEG)) 242 errnum = ERR_READ; 243 244 bufaddr = (char *) BUFFERADDR + byte_offset; 245 } 246 } 247 else 248 buf_track = track; 249 250 if ((buf_track == 0 || sector == 0) 251 && (PC_SLICE_TYPE (BUFFERADDR, 0) == PC_SLICE_TYPE_EZD 252 || PC_SLICE_TYPE (BUFFERADDR, 1) == PC_SLICE_TYPE_EZD 253 || PC_SLICE_TYPE (BUFFERADDR, 2) == PC_SLICE_TYPE_EZD 254 || PC_SLICE_TYPE (BUFFERADDR, 3) == PC_SLICE_TYPE_EZD)) 255 { 256 /* This is a EZD disk map sector 0 to sector 1 */ 257 if (buf_track == 0 || slen >= 2) 258 { 259 /* We already read the sector 1, copy it to sector 0 */ 260 memmove ((char *) BUFFERADDR, 261 (char *) BUFFERADDR + buf_geom.sector_size, 262 buf_geom.sector_size); 263 } 264 else 265 { 266 if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 267 1, 1, BUFFERSEG)) 268 errnum = ERR_READ; 269 } 270 } 271 } 272 273 if (size > ((num_sect << sector_size_bits) - byte_offset)) 274 size = (num_sect << sector_size_bits) - byte_offset; 275 276 /* 277 * Instrumentation to tell which sectors were read and used. 278 */ 279 if (disk_read_func) 280 { 281 unsigned long long sector_num = sector; 282 int length = buf_geom.sector_size - byte_offset; 283 if (length > size) 284 length = size; 285 (*disk_read_func) (sector_num++, byte_offset, length); 286 length = size - length; 287 if (length > 0) 288 { 289 while (length > buf_geom.sector_size) 290 { 291 (*disk_read_func) (sector_num++, 0, buf_geom.sector_size); 292 length -= buf_geom.sector_size; 293 } 294 (*disk_read_func) (sector_num, 0, length); 295 } 296 } 297 298 grub_memmove (buf, bufaddr, size); 299 300 buf += size; 301 byte_len -= size; 302 sector += num_sect; 303 byte_offset = 0; 304 } 305 306 return (!errnum); 307 } 308 309 310 int 311 devread(unsigned long long sector, int byte_offset, int byte_len, char *buf) 312 { 313 /* 314 * Check partition boundaries 315 */ 316 if ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) 317 >= part_length) 318 { 319 errnum = ERR_OUTSIDE_PART; 320 return 0; 321 } 322 323 /* 324 * Get the read to the beginning of a partition. 325 */ 326 sector += byte_offset >> SECTOR_BITS; 327 byte_offset &= SECTOR_SIZE - 1; 328 329 #if !defined(STAGE1_5) 330 if (disk_read_hook && debug) 331 printf ("<%llu, %d, %d>", sector, byte_offset, byte_len); 332 #endif /* !STAGE1_5 */ 333 334 /* 335 * Call RAWREAD, which is very similar, but: 336 * 337 * -- It takes an extra parameter, the drive number. 338 * -- It requires that "sector" is relative to the beginning 339 * of the disk. 340 * -- It doesn't handle offsets of more than 511 bytes into the 341 * sector. 342 */ 343 return rawread (current_drive, part_start + sector, byte_offset, 344 byte_len, buf); 345 } 346 347 #ifndef STAGE1_5 348 int 349 rawwrite(int drive, unsigned long long sector, char *buf) 350 { 351 if (sector == 0) 352 { 353 if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 0, 1, SCRATCHSEG)) 354 { 355 errnum = ERR_WRITE; 356 return 0; 357 } 358 359 if (PC_SLICE_TYPE (SCRATCHADDR, 0) == PC_SLICE_TYPE_EZD 360 || PC_SLICE_TYPE (SCRATCHADDR, 1) == PC_SLICE_TYPE_EZD 361 || PC_SLICE_TYPE (SCRATCHADDR, 2) == PC_SLICE_TYPE_EZD 362 || PC_SLICE_TYPE (SCRATCHADDR, 3) == PC_SLICE_TYPE_EZD) 363 sector = 1; 364 } 365 366 memmove ((char *) SCRATCHADDR, buf, SECTOR_SIZE); 367 if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom, 368 sector, 1, SCRATCHSEG)) 369 { 370 errnum = ERR_WRITE; 371 return 0; 372 } 373 374 if (sector - sector % buf_geom.sectors == buf_track) 375 /* Clear the cache. */ 376 buf_track = BUF_CACHE_INVALID; 377 378 return 1; 379 } 380 381 int 382 devwrite(unsigned long long sector, int sector_count, char *buf) 383 { 384 #if defined(GRUB_UTIL) && defined(__linux__) 385 if (current_partition != 0xFFFFFF 386 && is_disk_device (device_map, current_drive)) 387 { 388 /* If the grub shell is running under Linux and the user wants to 389 embed a Stage 1.5 into a partition instead of a MBR, use system 390 calls directly instead of biosdisk, because of the bug in 391 Linux. *sigh* */ 392 return write_to_partition (device_map, current_drive, current_partition, 393 sector, sector_count, buf); 394 } 395 else 396 #endif /* GRUB_UTIL && __linux__ */ 397 { 398 int i; 399 400 for (i = 0; i < sector_count; i++) 401 { 402 if (! rawwrite (current_drive, part_start + sector + i, 403 buf + (i << SECTOR_BITS))) 404 return 0; 405 406 } 407 return 1; 408 } 409 } 410 411 static int 412 sane_partition (void) 413 { 414 /* network drive */ 415 if (current_drive == NETWORK_DRIVE) 416 return 1; 417 418 if (!(current_partition & 0xFF000000uL) 419 && ((current_drive & 0xFFFFFF7F) < 8 420 || current_drive == cdrom_drive) 421 && (current_partition & 0xFF) == 0xFF 422 && ((current_partition & 0xFF00) == 0xFF00 423 || (current_partition & 0xFF00) < 0x1000) 424 && ((current_partition >> 16) == 0xFF 425 || (current_drive & 0x80))) 426 return 1; 427 428 errnum = ERR_DEV_VALUES; 429 return 0; 430 } 431 #endif /* ! STAGE1_5 */ 432 433 static void 434 attempt_mount (void) 435 { 436 #ifndef STAGE1_5 437 for (fsys_type = 0; fsys_type < NUM_FSYS; fsys_type++) 438 if ((fsys_table[fsys_type].mount_func) ()) 439 break; 440 441 if (fsys_type == NUM_FSYS && errnum == ERR_NONE) 442 errnum = ERR_FSYS_MOUNT; 443 #else 444 fsys_type = 0; 445 if ((*(fsys_table[fsys_type].mount_func)) () != 1) 446 { 447 fsys_type = NUM_FSYS; 448 errnum = ERR_FSYS_MOUNT; 449 } 450 #endif 451 } 452 453 454 #ifndef STAGE1_5 455 /* Turn on the active flag for the partition SAVED_PARTITION in the 456 drive SAVED_DRIVE. If an error occurs, return zero, otherwise return 457 non-zero. */ 458 int 459 make_saved_active (void) 460 { 461 char mbr[512]; 462 463 if (saved_drive & 0x80) 464 { 465 /* Hard disk */ 466 int part = saved_partition >> 16; 467 468 /* If the partition is not a primary partition, the active flag is 469 meaningless. (XXX: Really?) */ 470 if (part > 3) 471 { 472 errnum = ERR_DEV_VALUES; 473 return 0; 474 } 475 476 /* Read the MBR in the scratch space. */ 477 if (! rawread (saved_drive, 0, 0, SECTOR_SIZE, mbr)) 478 return 0; 479 480 /* If the partition is an extended partition, setting the active 481 flag violates the specification by IBM. */ 482 if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (mbr, part))) 483 { 484 errnum = ERR_DEV_VALUES; 485 return 0; 486 } 487 488 /* Check if the active flag is disabled. */ 489 if (PC_SLICE_FLAG (mbr, part) != PC_SLICE_FLAG_BOOTABLE) 490 { 491 int i; 492 493 /* Clear all the active flags in this table. */ 494 for (i = 0; i < 4; i++) 495 PC_SLICE_FLAG (mbr, i) = 0; 496 497 /* Set the flag. */ 498 PC_SLICE_FLAG (mbr, part) = PC_SLICE_FLAG_BOOTABLE; 499 500 /* Write back the MBR. */ 501 if (! rawwrite (saved_drive, 0, mbr)) 502 return 0; 503 } 504 } 505 else 506 { 507 /* If the drive is not a hard disk drive, you shouldn't call this 508 function. (XXX: Should I just ignore this error?) */ 509 errnum = ERR_DEV_VALUES; 510 return 0; 511 } 512 513 return 1; 514 } 515 516 /* Hide/Unhide CURRENT_PARTITION. */ 517 int 518 set_partition_hidden_flag (int hidden) 519 { 520 unsigned long part = 0xFFFFFF; 521 unsigned long long start, len, offset, ext_offset, gpt_offset; 522 int entry, type, gpt_count, gpt_size; 523 char mbr[512]; 524 525 /* The drive must be a hard disk. */ 526 if (! (current_drive & 0x80)) 527 { 528 errnum = ERR_BAD_ARGUMENT; 529 return 1; 530 } 531 532 /* The partition must be a PC slice. */ 533 if ((current_partition >> 16) == 0xFF 534 || (current_partition & 0xFFFF) != 0xFFFF) 535 { 536 errnum = ERR_BAD_ARGUMENT; 537 return 1; 538 } 539 540 /* Look for the partition. */ 541 while (next_partition (current_drive, 0xFFFFFF, &part, &type, 542 &start, &len, &offset, &entry, 543 &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) 544 { 545 /* The partition may not be a GPT partition. */ 546 if (gpt_offset != 0) 547 { 548 errnum = ERR_BAD_ARGUMENT; 549 return 1; 550 } 551 552 if (part == current_partition) 553 { 554 /* Found. */ 555 if (hidden) 556 PC_SLICE_TYPE (mbr, entry) |= PC_SLICE_TYPE_HIDDEN_FLAG; 557 else 558 PC_SLICE_TYPE (mbr, entry) &= ~PC_SLICE_TYPE_HIDDEN_FLAG; 559 560 /* Write back the MBR to the disk. */ 561 buf_track = BUF_CACHE_INVALID; 562 if (! rawwrite (current_drive, offset, mbr)) 563 return 1; 564 565 /* Succeed. */ 566 return 0; 567 } 568 } 569 570 return 1; 571 } 572 573 574 static void 575 check_and_print_mount (void) 576 { 577 attempt_mount (); 578 if (errnum == ERR_FSYS_MOUNT) 579 errnum = ERR_NONE; 580 if (!errnum) 581 print_fsys_type (); 582 print_error (); 583 } 584 #endif /* STAGE1_5 */ 585 586 587 /* Get the information on next partition on the drive DRIVE. 588 The caller must not modify the contents of the arguments when 589 iterating this function. The partition representation in GRUB will 590 be stored in *PARTITION. Likewise, the partition type in *TYPE, the 591 start sector in *START, the length in *LEN, the offset of the 592 partition table in *OFFSET, the entry number in the table in *ENTRY, 593 the offset of the extended partition in *EXT_OFFSET. 594 BUF is used to store a MBR, the boot sector of a partition, or 595 a BSD label sector, and it must be at least 512 bytes length. 596 When calling this function first, *PARTITION must be initialized to 597 0xFFFFFF. The return value is zero if fails, otherwise non-zero. */ 598 int 599 next_partition (unsigned long drive, unsigned long dest, 600 unsigned long *partition, int *type, 601 unsigned long long *start, unsigned long long *len, 602 unsigned long long *offset, int *entry, 603 unsigned long long *ext_offset, 604 unsigned long long *gpt_offset, int *gpt_count, 605 int *gpt_size, char *buf) 606 { 607 /* Forward declarations. */ 608 auto int next_bsd_partition (void); 609 auto int next_solaris_partition(void); 610 auto int next_pc_slice (void); 611 auto int next_gpt_slice(void); 612 613 /* Get next BSD partition in current PC slice. */ 614 int next_bsd_partition (void) 615 { 616 int i; 617 int bsd_part_no = (*partition & 0xFF00) >> 8; 618 619 /* If this is the first time... */ 620 if (bsd_part_no == 0xFF) 621 { 622 /* Check if the BSD label is within current PC slice. */ 623 if (*len < BSD_LABEL_SECTOR + 1) 624 { 625 errnum = ERR_BAD_PART_TABLE; 626 return 0; 627 } 628 629 /* Read the BSD label. */ 630 if (! rawread (drive, *start + BSD_LABEL_SECTOR, 631 0, SECTOR_SIZE, buf)) 632 return 0; 633 634 /* Check if it is valid. */ 635 if (! BSD_LABEL_CHECK_MAG (buf)) 636 { 637 errnum = ERR_BAD_PART_TABLE; 638 return 0; 639 } 640 641 bsd_part_no = -1; 642 } 643 644 /* Search next valid BSD partition. */ 645 for (i = bsd_part_no + 1; i < BSD_LABEL_NPARTS (buf); i++) 646 { 647 if (BSD_PART_TYPE (buf, i)) 648 { 649 /* Note that *TYPE and *PARTITION were set 650 for current PC slice. */ 651 *type = (BSD_PART_TYPE (buf, i) << 8) | (*type & 0xFF); 652 *start = BSD_PART_START (buf, i); 653 *len = BSD_PART_LENGTH (buf, i); 654 *partition = (*partition & 0xFF00FF) | (i << 8); 655 656 #ifndef STAGE1_5 657 /* XXX */ 658 if ((drive & 0x80) && BSD_LABEL_DTYPE (buf) == DTYPE_SCSI) 659 bsd_evil_hack = 4; 660 #endif /* ! STAGE1_5 */ 661 662 return 1; 663 } 664 } 665 666 errnum = ERR_NO_PART; 667 return 0; 668 } 669 670 /* Get next Solaris partition in current PC slice. */ 671 int next_solaris_partition (void) 672 { 673 static unsigned long pcs_start; 674 int i; 675 int sol_part_no = (*partition & 0xFF00) >> 8; 676 677 /* If this is the first time... */ 678 if (sol_part_no == 0xFF) 679 { 680 /* Check if the Solaris label is within current PC slice. */ 681 if (*len < SOL_LABEL_LOC + 1) 682 { 683 errnum = ERR_BAD_PART_TABLE; 684 return 0; 685 } 686 687 /* Read the Solaris label. */ 688 if (! rawread (drive, *start + SOL_LABEL_LOC, 0, SECTOR_SIZE, buf)) 689 return 0; 690 691 /* Check if it is valid. */ 692 if (! SOL_LABEL_CHECK_MAG (buf)) 693 { 694 errnum = ERR_BAD_PART_TABLE; 695 return 0; 696 } 697 698 sol_part_no = -1; 699 pcs_start = *start; /* save the start of pc slice */ 700 } 701 702 /* Search next valid Solaris partition. */ 703 for (i = sol_part_no + 1; i < SOL_LABEL_NPARTS; i++) 704 { 705 if (SOL_PART_EXISTS (buf, i)) 706 { 707 /* SOL_PART_START is relative to fdisk partition */ 708 *start = SOL_PART_START (buf, i) + pcs_start; 709 *len = SOL_PART_LENGTH (buf, i); 710 *partition = (*partition & 0xFF00FF) | (i << 8); 711 712 return 1; 713 } 714 } 715 716 errnum = ERR_NO_PART; 717 return 0; 718 } 719 720 /* Get next PC slice. Be careful of that this function may return 721 an empty PC slice (i.e. a partition whose type is zero) as well. */ 722 int next_pc_slice (void) 723 { 724 int pc_slice_no = (*partition & 0xFF0000) >> 16; 725 726 /* If this is the first time... */ 727 if (pc_slice_no == 0xFF) 728 { 729 *offset = 0; 730 *ext_offset = 0; 731 *entry = -1; 732 pc_slice_no = -1; 733 } 734 735 /* Read the MBR or the boot sector of the extended partition. */ 736 if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) 737 return 0; 738 739 /* Check if it is valid. */ 740 if (! PC_MBR_CHECK_SIG (buf)) 741 { 742 errnum = ERR_BAD_PART_TABLE; 743 return 0; 744 } 745 746 /* If this is a GPT partition table, read it as such. */ 747 if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT) 748 { 749 struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf; 750 751 /* Read in the GPT Partition table header. */ 752 if (! rawread (drive, 1, 0, SECTOR_SIZE, buf)) 753 return 0; 754 755 if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000) 756 { 757 /* Let gpt_offset point to the first entry in the GPT 758 partition table. This can also be used by callers of 759 next_partition to determine if a entry comes from a 760 GPT partition table or not. */ 761 *gpt_offset = hdr->partitions; 762 *gpt_count = hdr->maxpart; 763 *gpt_size = hdr->partentry_size; 764 765 return next_gpt_slice(); 766 } 767 else 768 { 769 /* This is not a valid header for a GPT partition table. 770 Re-read the MBR or the boot sector of the extended 771 partition. */ 772 if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) 773 return 0; 774 } 775 } 776 777 /* Not a GPT partition. */ 778 *gpt_offset = 0; 779 780 /* Increase the entry number. */ 781 (*entry)++; 782 783 /* If this is out of current partition table... */ 784 if (*entry == PC_SLICE_MAX) 785 { 786 int i; 787 788 /* Search the first extended partition in current table. */ 789 for (i = 0; i < PC_SLICE_MAX; i++) 790 { 791 if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (buf, i))) 792 { 793 /* Found. Set the new offset and the entry number, 794 and restart this function. */ 795 *offset = *ext_offset + PC_SLICE_START (buf, i); 796 if (! *ext_offset) 797 *ext_offset = *offset; 798 *entry = -1; 799 return next_pc_slice (); 800 } 801 } 802 803 errnum = ERR_NO_PART; 804 return 0; 805 } 806 807 *type = PC_SLICE_TYPE (buf, *entry); 808 *start = *offset + PC_SLICE_START (buf, *entry); 809 *len = PC_SLICE_LENGTH (buf, *entry); 810 811 /* The calculation of a PC slice number is complicated, because of 812 the rather odd definition of extended partitions. Even worse, 813 there is no guarantee that this is consistent with every 814 operating systems. Uggh. */ 815 if (pc_slice_no < PC_SLICE_MAX 816 || (! IS_PC_SLICE_TYPE_EXTENDED (*type) 817 && *type != PC_SLICE_TYPE_NONE)) 818 pc_slice_no++; 819 820 *partition = (pc_slice_no << 16) | 0xFFFF; 821 return 1; 822 } 823 824 /* Get the next GPT slice. */ 825 int next_gpt_slice (void) 826 { 827 struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf; 828 /* Make GPT partitions show up as PC slices. */ 829 int pc_slice_no = (*partition & 0xFF0000) >> 16; 830 831 /* If this is the first time... */ 832 if (pc_slice_no == 0xFF) 833 { 834 pc_slice_no = -1; 835 *entry = -1; 836 } 837 838 do { 839 (*entry)++; 840 841 if (*entry >= *gpt_count) 842 { 843 errnum = ERR_NO_PART; 844 return 0; 845 } 846 /* Read in the GPT Partition table entry. */ 847 if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf)) 848 return 0; 849 } while (! (gptentry->type1 && gptentry->type2)); 850 851 pc_slice_no++; 852 *start = gptentry->start; 853 *len = gptentry->end - gptentry->start + 1; 854 *type = PC_SLICE_TYPE_EXT2FS; 855 *entry = pc_slice_no; 856 *partition = (*entry << 16) | 0xFFFF; 857 858 return 1; 859 } 860 861 /* Start the body of this function. */ 862 863 #ifndef STAGE1_5 864 if (current_drive == NETWORK_DRIVE) 865 return 0; 866 #endif 867 868 /* check for Solaris partition */ 869 if (*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_SOLARIS (*type & 0xff)) 870 { 871 if (next_solaris_partition ()) 872 return 1; 873 errnum = ERR_NONE; 874 } 875 876 if (*partition != 0xFFFFFF && *gpt_offset != 0) 877 return next_gpt_slice (); 878 879 /* If previous partition is a BSD partition or a PC slice which 880 contains BSD partitions... */ 881 if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff)) 882 || ! (drive & 0x80)) 883 { 884 if (*type == PC_SLICE_TYPE_NONE) 885 *type = PC_SLICE_TYPE_FREEBSD; 886 887 /* Get next BSD partition, if any. */ 888 if (next_bsd_partition ()) 889 return 1; 890 891 /* If the destination partition is a BSD partition and current 892 BSD partition has any error, abort the operation. */ 893 if ((dest & 0xFF00) != 0xFF00 894 && ((dest & 0xFF0000) == 0xFF0000 895 || (dest & 0xFF0000) == (*partition & 0xFF0000))) 896 return 0; 897 898 /* Ignore the error. */ 899 errnum = ERR_NONE; 900 } 901 902 return next_pc_slice (); 903 } 904 905 #ifndef STAGE1_5 906 static unsigned long cur_part_offset; 907 static unsigned long cur_part_addr; 908 #endif 909 910 /* Open a partition. */ 911 int 912 real_open_partition (int flags) 913 { 914 unsigned long dest_partition = current_partition; 915 unsigned long long part_offset; 916 unsigned long long ext_offset; 917 unsigned long long gpt_offset; 918 int gpt_count; 919 int gpt_size; 920 int entry; 921 char buf[SECTOR_SIZE]; 922 int unix_part, pc_slice; 923 924 /* For simplicity. */ 925 auto int next (void); 926 int next (void) 927 { 928 int ret = next_partition (current_drive, dest_partition, 929 ¤t_partition, ¤t_slice, 930 &part_start, &part_length, 931 &part_offset, &entry, &ext_offset, 932 &gpt_offset, &gpt_count, &gpt_size, buf); 933 unix_part = (current_partition >> 8) & 0xFF; 934 pc_slice = current_partition >> 16; 935 return ret; 936 } 937 938 #ifndef STAGE1_5 939 /* network drive */ 940 if (current_drive == NETWORK_DRIVE) 941 return 1; 942 943 if (! sane_partition ()) 944 return 0; 945 #endif 946 947 bsd_evil_hack = 0; 948 current_slice = 0; 949 part_start = 0; 950 951 /* Make sure that buf_geom is valid. */ 952 if (buf_drive != current_drive) 953 { 954 if (get_diskinfo (current_drive, &buf_geom)) 955 { 956 errnum = ERR_NO_DISK; 957 return 0; 958 } 959 buf_drive = current_drive; 960 buf_track = BUF_CACHE_INVALID; 961 } 962 part_length = 963 (buf_geom.total_sectors > MAXUINT) ? MAXUINT : buf_geom.total_sectors; 964 965 /* If this is the whole disk, return here. */ 966 if (! flags && current_partition == 0xFFFFFF) 967 return 1; 968 969 if (flags) 970 dest_partition = 0xFFFFFF; 971 972 /* Initialize CURRENT_PARTITION for next_partition. */ 973 current_partition = 0xFFFFFF; 974 975 while (next ()) 976 { 977 #ifndef STAGE1_5 978 loop_start: 979 980 cur_part_offset = part_offset; 981 cur_part_addr = BOOT_PART_TABLE + (entry << 4); 982 #endif /* ! STAGE1_5 */ 983 984 /* If this is a valid partition... */ 985 if (current_slice) 986 { 987 #ifndef STAGE1_5 988 /* Display partition information. */ 989 if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice)) 990 { 991 if (! do_completion) 992 { 993 if (current_drive & 0x80) 994 grub_printf (" Partition num: %d, ", 995 current_partition >> 16); 996 997 if (! IS_PC_SLICE_TYPE_BSD (current_slice) && 998 ! IS_PC_SLICE_TYPE_SOLARIS (current_slice)) 999 check_and_print_mount (); 1000 else 1001 { 1002 int got_part = 0; 1003 int saved_slice = current_slice; 1004 1005 while (next ()) 1006 { 1007 if (unix_part == 0xFF) 1008 break; 1009 1010 if (! got_part) 1011 { 1012 grub_printf ("[BSD/SOLARIS sub-partitions immediately follow]\n"); 1013 got_part = 1; 1014 } 1015 1016 grub_printf (" BSD/SOLARIS Partition num: \'%c\', ", 1017 unix_part + 'a'); 1018 check_and_print_mount (); 1019 } 1020 1021 if (! got_part) 1022 grub_printf (" No BSD/SOLARIS sub-partition found, partition type 0x%x\n", 1023 saved_slice); 1024 1025 if (errnum) 1026 { 1027 errnum = ERR_NONE; 1028 break; 1029 } 1030 1031 goto loop_start; 1032 } 1033 } 1034 else 1035 { 1036 if (unix_part != 0xFF) 1037 { 1038 char str[16]; 1039 1040 if (! (current_drive & 0x80) 1041 || (dest_partition >> 16) == pc_slice) 1042 grub_sprintf (str, "%c)", unix_part + 'a'); 1043 else 1044 grub_sprintf (str, "%d,%c)", 1045 pc_slice, unix_part + 'a'); 1046 print_a_completion (str); 1047 } 1048 else if (! IS_PC_SLICE_TYPE_BSD (current_slice) && 1049 ! IS_PC_SLICE_TYPE_SOLARIS (current_slice)) 1050 { 1051 char str[8]; 1052 1053 grub_sprintf (str, "%d)", pc_slice); 1054 print_a_completion (str); 1055 } 1056 } 1057 } 1058 1059 errnum = ERR_NONE; 1060 #endif /* ! STAGE1_5 */ 1061 1062 /* Check if this is the destination partition. */ 1063 if (! flags 1064 && (dest_partition == current_partition 1065 || ((dest_partition >> 16) == 0xFF 1066 && ((dest_partition >> 8) & 0xFF) == unix_part))) 1067 return 1; 1068 } 1069 } 1070 1071 #ifndef STAGE1_5 1072 if (flags) 1073 { 1074 if (! (current_drive & 0x80)) 1075 { 1076 current_partition = 0xFFFFFF; 1077 check_and_print_mount (); 1078 } 1079 1080 errnum = ERR_NONE; 1081 return 1; 1082 } 1083 #endif /* ! STAGE1_5 */ 1084 1085 return 0; 1086 } 1087 1088 1089 int 1090 open_partition (void) 1091 { 1092 return real_open_partition (0); 1093 } 1094 1095 1096 #ifndef STAGE1_5 1097 /* XX used for device completion in 'set_device' and 'print_completions' */ 1098 static int incomplete, disk_choice; 1099 static enum 1100 { 1101 PART_UNSPECIFIED = 0, 1102 PART_DISK, 1103 PART_CHOSEN, 1104 } 1105 part_choice; 1106 #endif /* ! STAGE1_5 */ 1107 1108 char * 1109 set_device (char *device) 1110 { 1111 #ifdef STAGE1_5 1112 /* In Stage 1.5, the first 4 bytes of FILENAME has a device number. */ 1113 unsigned long dev = *((unsigned long *) device); 1114 int drive = (dev >> 24) & 0xFF; 1115 int partition = dev & 0xFFFFFF; 1116 1117 /* If DRIVE is disabled, use SAVED_DRIVE instead. */ 1118 if (drive == GRUB_INVALID_DRIVE) 1119 current_drive = saved_drive; 1120 else 1121 current_drive = drive; 1122 1123 /* The `partition' part must always have a valid number. */ 1124 current_partition = partition; 1125 1126 return device + sizeof (unsigned long); 1127 1128 #else /* ! STAGE1_5 */ 1129 1130 int result = 0; 1131 1132 incomplete = 0; 1133 disk_choice = 1; 1134 part_choice = PART_UNSPECIFIED; 1135 current_drive = saved_drive; 1136 current_partition = 0xFFFFFF; 1137 1138 if (*device == '(' && !*(device + 1)) 1139 /* user has given '(' only, let disk_choice handle what disks we have */ 1140 return device + 1; 1141 1142 if (*device == '(' && *(++device)) 1143 { 1144 if (*device != ',' && *device != ')') 1145 { 1146 char ch = *device; 1147 #ifdef SUPPORT_NETBOOT 1148 if (*device == 'f' || *device == 'h' 1149 || (*device == 'n' && network_ready) 1150 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1151 #else 1152 if (*device == 'f' || *device == 'h' 1153 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1154 #endif /* SUPPORT_NETBOOT */ 1155 { 1156 /* user has given '([fhn]', check for resp. add 'd' and 1157 let disk_choice handle what disks we have */ 1158 if (!*(device + 1)) 1159 { 1160 device++; 1161 *device++ = 'd'; 1162 *device = '\0'; 1163 return device; 1164 } 1165 else if (*(device + 1) == 'd' && !*(device + 2)) 1166 return device + 2; 1167 } 1168 1169 if ((*device == 'f' 1170 || *device == 'h' 1171 #ifdef SUPPORT_NETBOOT 1172 || (*device == 'n' && network_ready) 1173 #endif 1174 || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)) 1175 && (device += 2, (*(device - 1) != 'd'))) 1176 errnum = ERR_NUMBER_PARSING; 1177 1178 #ifdef SUPPORT_NETBOOT 1179 if (ch == 'n' && network_ready) 1180 current_drive = NETWORK_DRIVE; 1181 else 1182 #endif /* SUPPORT_NETBOOT */ 1183 { 1184 if (ch == 'c' && cdrom_drive != GRUB_INVALID_DRIVE) 1185 current_drive = cdrom_drive; 1186 else 1187 { 1188 safe_parse_maxint (&device, (int *) ¤t_drive); 1189 1190 disk_choice = 0; 1191 if (ch == 'h') 1192 current_drive += 0x80; 1193 } 1194 } 1195 } 1196 1197 if (errnum) 1198 return 0; 1199 1200 if (*device == ')') 1201 { 1202 part_choice = PART_CHOSEN; 1203 result = 1; 1204 } 1205 else if (*device == ',') 1206 { 1207 /* Either an absolute PC, BSD, or Solaris partition. */ 1208 disk_choice = 0; 1209 part_choice ++; 1210 device++; 1211 1212 if (*device >= '0' && *device <= '9') 1213 { 1214 part_choice ++; 1215 current_partition = 0; 1216 1217 if (!(current_drive & 0x80) 1218 || !safe_parse_maxint (&device, (int *) ¤t_partition) 1219 || current_partition > 254) 1220 { 1221 errnum = ERR_DEV_FORMAT; 1222 return 0; 1223 } 1224 1225 current_partition = (current_partition << 16) + 0xFFFF; 1226 1227 if (*device == ',') 1228 device++; 1229 1230 if (*device >= 'a' && *device <= 'p') 1231 { 1232 current_partition = (((*(device++) - 'a') << 8) 1233 | (current_partition & 0xFF00FF)); 1234 } 1235 } 1236 else if (*device >= 'a' && *device <= 'p') 1237 { 1238 part_choice ++; 1239 current_partition = ((*(device++) - 'a') << 8) | 0xFF00FF; 1240 } 1241 1242 if (*device == ')') 1243 { 1244 if (part_choice == PART_DISK) 1245 { 1246 current_partition = saved_partition; 1247 part_choice ++; 1248 } 1249 1250 result = 1; 1251 } 1252 } 1253 } 1254 1255 if (! sane_partition ()) 1256 return 0; 1257 1258 if (result) 1259 return device + 1; 1260 else 1261 { 1262 if (!*device) 1263 incomplete = 1; 1264 errnum = ERR_DEV_FORMAT; 1265 } 1266 1267 return 0; 1268 1269 #endif /* ! STAGE1_5 */ 1270 } 1271 1272 /* 1273 * This performs a "mount" on the current device, both drive and partition 1274 * number. 1275 */ 1276 1277 int 1278 open_device (void) 1279 { 1280 if (open_partition ()) 1281 attempt_mount (); 1282 1283 if (errnum != ERR_NONE) 1284 return 0; 1285 1286 return 1; 1287 } 1288 1289 1290 #ifndef STAGE1_5 1291 int 1292 set_bootdev (int hdbias) 1293 { 1294 int i, j; 1295 1296 /* Copy the boot partition information to 0x7be-0x7fd for chain-loading. */ 1297 if ((saved_drive & 0x80) && cur_part_addr) 1298 { 1299 if (rawread (saved_drive, cur_part_offset, 1300 0, SECTOR_SIZE, (char *) SCRATCHADDR)) 1301 { 1302 char *dst, *src; 1303 1304 /* Need only the partition table. 1305 XXX: We cannot use grub_memmove because BOOT_PART_TABLE 1306 (0x07be) is less than 0x1000. */ 1307 dst = (char *) BOOT_PART_TABLE; 1308 src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET; 1309 while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH) 1310 *dst++ = *src++; 1311 1312 /* Set the active flag of the booted partition. */ 1313 for (i = 0; i < 4; i++) 1314 PC_SLICE_FLAG (BOOT_PART_TABLE, i) = 0; 1315 1316 *((unsigned char *) cur_part_addr) = PC_SLICE_FLAG_BOOTABLE; 1317 boot_part_addr = cur_part_addr; 1318 } 1319 else 1320 return 0; 1321 } 1322 1323 /* 1324 * Set BSD boot device. 1325 */ 1326 i = (saved_partition >> 16) + 2; 1327 if (saved_partition == 0xFFFFFF) 1328 i = 1; 1329 else if ((saved_partition >> 16) == 0xFF) 1330 i = 0; 1331 1332 /* FIXME: extremely evil hack!!! */ 1333 j = 2; 1334 if (saved_drive & 0x80) 1335 j = bsd_evil_hack; 1336 1337 return MAKEBOOTDEV (j, (i >> 4), (i & 0xF), 1338 ((saved_drive - hdbias) & 0x7F), 1339 ((saved_partition >> 8) & 0xFF)); 1340 } 1341 #endif /* STAGE1_5 */ 1342 1343 1344 static char * 1345 setup_part (char *filename) 1346 { 1347 #ifdef STAGE1_5 1348 1349 if (! (filename = set_device (filename))) 1350 { 1351 current_drive = GRUB_INVALID_DRIVE; 1352 return 0; 1353 } 1354 1355 # ifndef NO_BLOCK_FILES 1356 if (*filename != '/') 1357 open_partition (); 1358 else 1359 # endif /* ! NO_BLOCK_FILES */ 1360 open_device (); 1361 1362 #else /* ! STAGE1_5 */ 1363 1364 if (*filename == '(') 1365 { 1366 if ((filename = set_device (filename)) == 0) 1367 { 1368 current_drive = GRUB_INVALID_DRIVE; 1369 return 0; 1370 } 1371 # ifndef NO_BLOCK_FILES 1372 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1373 open_partition (); 1374 else 1375 # endif /* ! NO_BLOCK_FILES */ 1376 open_device (); 1377 } 1378 else if (saved_drive != current_drive 1379 || saved_partition != current_partition 1380 || (*filename == '/' && fsys_type == NUM_FSYS) 1381 || buf_drive == -1) 1382 { 1383 current_drive = saved_drive; 1384 current_partition = saved_partition; 1385 /* allow for the error case of "no filesystem" after the partition 1386 is found. This makes block files work fine on no filesystem */ 1387 # ifndef NO_BLOCK_FILES 1388 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1389 open_partition (); 1390 else 1391 # endif /* ! NO_BLOCK_FILES */ 1392 open_device (); 1393 } 1394 1395 #endif /* ! STAGE1_5 */ 1396 1397 if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT)) 1398 return 0; 1399 else 1400 errnum = 0; 1401 1402 #ifndef STAGE1_5 1403 if (!sane_partition ()) 1404 return 0; 1405 #endif 1406 1407 return filename; 1408 } 1409 1410 1411 #ifndef STAGE1_5 1412 /* 1413 * This prints the filesystem type or gives relevant information. 1414 */ 1415 1416 void 1417 print_fsys_type (void) 1418 { 1419 if (! do_completion) 1420 { 1421 grub_printf (" Filesystem type "); 1422 1423 if (fsys_type != NUM_FSYS) 1424 grub_printf ("is %s, ", fsys_table[fsys_type].name); 1425 else 1426 grub_printf ("unknown, "); 1427 1428 if (current_partition == 0xFFFFFF) 1429 grub_printf ("using whole disk\n"); 1430 else 1431 grub_printf ("partition type 0x%x\n", current_slice & 0xFF); 1432 } 1433 } 1434 #endif /* STAGE1_5 */ 1435 1436 #ifndef STAGE1_5 1437 /* If DO_COMPLETION is true, just print NAME. Otherwise save the unique 1438 part into UNIQUE_STRING. */ 1439 void 1440 print_a_completion (char *name) 1441 { 1442 /* If NAME is "." or "..", do not count it. */ 1443 if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0) 1444 return; 1445 1446 if (do_completion) 1447 { 1448 char *buf = unique_string; 1449 1450 if (! unique) 1451 while ((*buf++ = *name++)) 1452 ; 1453 else 1454 { 1455 while (*buf && (*buf == *name)) 1456 { 1457 buf++; 1458 name++; 1459 } 1460 /* mismatch, strip it. */ 1461 *buf = '\0'; 1462 } 1463 } 1464 else 1465 grub_printf (" %s", name); 1466 1467 unique++; 1468 } 1469 1470 /* 1471 * This lists the possible completions of a device string, filename, or 1472 * any sane combination of the two. 1473 */ 1474 1475 int 1476 print_completions (int is_filename, int is_completion) 1477 { 1478 char *buf = (char *) COMPLETION_BUF; 1479 char *ptr = buf; 1480 1481 unique_string = (char *) UNIQUE_BUF; 1482 *unique_string = 0; 1483 unique = 0; 1484 do_completion = is_completion; 1485 1486 if (! is_filename) 1487 { 1488 /* Print the completions of builtin commands. */ 1489 struct builtin **builtin; 1490 1491 if (! is_completion) 1492 grub_printf (" Possible commands are:"); 1493 1494 for (builtin = builtin_table; (*builtin); builtin++) 1495 { 1496 /* If *BUILTIN cannot be run in the command-line, skip it. */ 1497 if (! ((*builtin)->flags & BUILTIN_CMDLINE)) 1498 continue; 1499 1500 if (substring (buf, (*builtin)->name) <= 0) 1501 print_a_completion ((*builtin)->name); 1502 } 1503 1504 if (is_completion && *unique_string) 1505 { 1506 if (unique == 1) 1507 { 1508 char *u = unique_string + grub_strlen (unique_string); 1509 1510 *u++ = ' '; 1511 *u = 0; 1512 } 1513 1514 grub_strcpy (buf, unique_string); 1515 } 1516 1517 if (! is_completion) 1518 grub_putchar ('\n'); 1519 1520 print_error (); 1521 do_completion = 0; 1522 if (errnum) 1523 return -1; 1524 else 1525 return unique - 1; 1526 } 1527 1528 if (*buf == '/' || (ptr = set_device (buf)) || incomplete) 1529 { 1530 errnum = 0; 1531 1532 if (*buf == '(' && (incomplete || ! *ptr)) 1533 { 1534 if (! part_choice) 1535 { 1536 /* disk completions */ 1537 int disk_no, i, j; 1538 struct geometry geom; 1539 1540 if (! is_completion) 1541 grub_printf (" Possible disks are: "); 1542 1543 if (!ptr 1544 || *(ptr-1) != 'd' 1545 #ifdef SUPPORT_NETBOOT 1546 || *(ptr-2) != 'n' 1547 #endif /* SUPPORT_NETBOOT */ 1548 || *(ptr-2) != 'c') 1549 { 1550 for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0); 1551 i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2); 1552 i++) 1553 { 1554 for (j = 0; j < 8; j++) 1555 { 1556 disk_no = (i * 0x80) + j; 1557 if ((disk_choice || disk_no == current_drive) 1558 && ! get_diskinfo (disk_no, &geom)) 1559 { 1560 char dev_name[8]; 1561 1562 grub_sprintf (dev_name, "%cd%d", i ? 'h':'f', j); 1563 print_a_completion (dev_name); 1564 } 1565 } 1566 } 1567 } 1568 1569 if (cdrom_drive != GRUB_INVALID_DRIVE 1570 && (disk_choice || cdrom_drive == current_drive) 1571 && (!ptr 1572 || *(ptr-1) == '(' 1573 || (*(ptr-1) == 'd' && *(ptr-2) == 'c'))) 1574 print_a_completion ("cd"); 1575 1576 # ifdef SUPPORT_NETBOOT 1577 if (network_ready 1578 && (disk_choice || NETWORK_DRIVE == current_drive) 1579 && (!ptr 1580 || *(ptr-1) == '(' 1581 || (*(ptr-1) == 'd' && *(ptr-2) == 'n'))) 1582 print_a_completion ("nd"); 1583 # endif /* SUPPORT_NETBOOT */ 1584 1585 if (is_completion && *unique_string) 1586 { 1587 ptr = buf; 1588 while (*ptr != '(') 1589 ptr--; 1590 ptr++; 1591 grub_strcpy (ptr, unique_string); 1592 if (unique == 1) 1593 { 1594 ptr += grub_strlen (ptr); 1595 if (*unique_string == 'h') 1596 { 1597 *ptr++ = ','; 1598 *ptr = 0; 1599 } 1600 else 1601 { 1602 *ptr++ = ')'; 1603 *ptr = 0; 1604 } 1605 } 1606 } 1607 1608 if (! is_completion) 1609 grub_putchar ('\n'); 1610 } 1611 else 1612 { 1613 /* partition completions */ 1614 if (part_choice == PART_CHOSEN 1615 && open_partition () 1616 && ! IS_PC_SLICE_TYPE_BSD (current_slice)) 1617 { 1618 unique = 1; 1619 ptr = buf + grub_strlen (buf); 1620 if (*(ptr - 1) != ')') 1621 { 1622 *ptr++ = ')'; 1623 *ptr = 0; 1624 } 1625 } 1626 else 1627 { 1628 if (! is_completion) 1629 grub_printf (" Possible partitions are:\n"); 1630 real_open_partition (1); 1631 1632 if (is_completion && *unique_string) 1633 { 1634 ptr = buf; 1635 while (*ptr++ != ',') 1636 ; 1637 grub_strcpy (ptr, unique_string); 1638 } 1639 } 1640 } 1641 } 1642 else if (ptr && *ptr == '/') 1643 { 1644 /* filename completions */ 1645 if (! is_completion) 1646 grub_printf (" Possible files are:"); 1647 1648 dir (buf); 1649 1650 if (is_completion && *unique_string) 1651 { 1652 ptr += grub_strlen (ptr); 1653 while (*ptr != '/') 1654 ptr--; 1655 ptr++; 1656 1657 grub_strcpy (ptr, unique_string); 1658 1659 if (unique == 1) 1660 { 1661 ptr += grub_strlen (unique_string); 1662 1663 /* Check if the file UNIQUE_STRING is a directory. */ 1664 *ptr = '/'; 1665 *(ptr + 1) = 0; 1666 1667 dir (buf); 1668 1669 /* Restore the original unique value. */ 1670 unique = 1; 1671 1672 if (errnum) 1673 { 1674 /* Regular file */ 1675 errnum = 0; 1676 *ptr = ' '; 1677 *(ptr + 1) = 0; 1678 } 1679 } 1680 } 1681 1682 if (! is_completion) 1683 grub_putchar ('\n'); 1684 } 1685 else 1686 errnum = ERR_BAD_FILENAME; 1687 } 1688 1689 print_error (); 1690 do_completion = 0; 1691 if (errnum) 1692 return -1; 1693 else 1694 return unique - 1; 1695 } 1696 #endif /* STAGE1_5 */ 1697 1698 1699 /* 1700 * This is the generic file open function. 1701 */ 1702 1703 int 1704 grub_open (char *filename) 1705 { 1706 #ifndef NO_DECOMPRESSION 1707 compressed_file = 0; 1708 #endif /* NO_DECOMPRESSION */ 1709 1710 /* if any "dir" function uses/sets filepos, it must 1711 set it to zero before returning if opening a file! */ 1712 filepos = 0; 1713 1714 if (!(filename = setup_part (filename))) 1715 return 0; 1716 1717 #ifndef NO_BLOCK_FILES 1718 block_file = 0; 1719 #endif /* NO_BLOCK_FILES */ 1720 1721 /* This accounts for partial filesystem implementations. */ 1722 fsmax = MAXINT; 1723 1724 if (*filename != '/' && current_drive != NETWORK_DRIVE) 1725 { 1726 #ifndef NO_BLOCK_FILES 1727 char *ptr = filename; 1728 int tmp, list_addr = BLK_BLKLIST_START; 1729 filemax = 0; 1730 1731 while (list_addr < BLK_MAX_ADDR) 1732 { 1733 tmp = 0; 1734 safe_parse_maxint (&ptr, &tmp); 1735 errnum = 0; 1736 1737 if (*ptr != '+') 1738 { 1739 if ((*ptr && *ptr != '/' && !isspace (*ptr)) 1740 || tmp == 0 || tmp > filemax) 1741 errnum = ERR_BAD_FILENAME; 1742 else 1743 filemax = tmp; 1744 1745 break; 1746 } 1747 1748 /* since we use the same filesystem buffer, mark it to 1749 be remounted */ 1750 fsys_type = NUM_FSYS; 1751 1752 BLK_BLKSTART (list_addr) = tmp; 1753 ptr++; 1754 1755 if (!safe_parse_maxint (&ptr, &tmp) 1756 || tmp == 0 1757 || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr))) 1758 { 1759 errnum = ERR_BAD_FILENAME; 1760 break; 1761 } 1762 1763 BLK_BLKLENGTH (list_addr) = tmp; 1764 1765 filemax += (tmp * SECTOR_SIZE); 1766 list_addr += BLK_BLKLIST_INC_VAL; 1767 1768 if (*ptr != ',') 1769 break; 1770 1771 ptr++; 1772 } 1773 1774 if (list_addr < BLK_MAX_ADDR && ptr != filename && !errnum) 1775 { 1776 block_file = 1; 1777 BLK_CUR_FILEPOS = 0; 1778 BLK_CUR_BLKLIST = BLK_BLKLIST_START; 1779 BLK_CUR_BLKNUM = 0; 1780 1781 #ifndef NO_DECOMPRESSION 1782 return gunzip_test_header (); 1783 #else /* NO_DECOMPRESSION */ 1784 return 1; 1785 #endif /* NO_DECOMPRESSION */ 1786 } 1787 #else /* NO_BLOCK_FILES */ 1788 errnum = ERR_BAD_FILENAME; 1789 #endif /* NO_BLOCK_FILES */ 1790 } 1791 1792 if (!errnum && fsys_type == NUM_FSYS) 1793 errnum = ERR_FSYS_MOUNT; 1794 1795 # ifndef STAGE1_5 1796 /* set "dir" function to open a file */ 1797 print_possibilities = 0; 1798 # endif 1799 1800 if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename)) 1801 { 1802 #ifndef NO_DECOMPRESSION 1803 return gunzip_test_header (); 1804 #else /* NO_DECOMPRESSION */ 1805 return 1; 1806 #endif /* NO_DECOMPRESSION */ 1807 } 1808 1809 return 0; 1810 } 1811 1812 1813 int 1814 grub_read (char *buf, int len) 1815 { 1816 /* Make sure "filepos" is a sane value */ 1817 if ((filepos < 0) || (filepos > filemax)) 1818 filepos = filemax; 1819 1820 /* Make sure "len" is a sane value */ 1821 if ((len < 0) || (len > (filemax - filepos))) 1822 len = filemax - filepos; 1823 1824 /* if target file position is past the end of 1825 the supported/configured filesize, then 1826 there is an error */ 1827 if (filepos + len > fsmax) 1828 { 1829 errnum = ERR_FILELENGTH; 1830 return 0; 1831 } 1832 1833 #ifndef NO_DECOMPRESSION 1834 if (compressed_file) 1835 return gunzip_read (buf, len); 1836 #endif /* NO_DECOMPRESSION */ 1837 1838 #ifndef NO_BLOCK_FILES 1839 if (block_file) 1840 { 1841 int size, off, ret = 0; 1842 1843 while (len && !errnum) 1844 { 1845 /* we may need to look for the right block in the list(s) */ 1846 if (filepos < BLK_CUR_FILEPOS) 1847 { 1848 BLK_CUR_FILEPOS = 0; 1849 BLK_CUR_BLKLIST = BLK_BLKLIST_START; 1850 BLK_CUR_BLKNUM = 0; 1851 } 1852 1853 /* run BLK_CUR_FILEPOS up to filepos */ 1854 while (filepos > BLK_CUR_FILEPOS) 1855 { 1856 if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1))) 1857 >= SECTOR_SIZE) 1858 { 1859 BLK_CUR_FILEPOS += SECTOR_SIZE; 1860 BLK_CUR_BLKNUM++; 1861 1862 if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST)) 1863 { 1864 BLK_CUR_BLKLIST += BLK_BLKLIST_INC_VAL; 1865 BLK_CUR_BLKNUM = 0; 1866 } 1867 } 1868 else 1869 BLK_CUR_FILEPOS = filepos; 1870 } 1871 1872 off = filepos & (SECTOR_SIZE - 1); 1873 size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM) 1874 * SECTOR_SIZE) - off; 1875 if (size > len) 1876 size = len; 1877 1878 disk_read_func = disk_read_hook; 1879 1880 /* read current block and put it in the right place in memory */ 1881 devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM, 1882 off, size, buf); 1883 1884 disk_read_func = NULL; 1885 1886 len -= size; 1887 filepos += size; 1888 ret += size; 1889 buf += size; 1890 } 1891 1892 if (errnum) 1893 ret = 0; 1894 1895 return ret; 1896 } 1897 #endif /* NO_BLOCK_FILES */ 1898 1899 if (fsys_type == NUM_FSYS) 1900 { 1901 errnum = ERR_FSYS_MOUNT; 1902 return 0; 1903 } 1904 1905 return (*(fsys_table[fsys_type].read_func)) (buf, len); 1906 } 1907 1908 #ifndef STAGE1_5 1909 /* Reposition a file offset. */ 1910 int 1911 grub_seek (int offset) 1912 { 1913 if (offset > filemax || offset < 0) 1914 return -1; 1915 1916 filepos = offset; 1917 return offset; 1918 } 1919 1920 int 1921 dir (char *dirname) 1922 { 1923 #ifndef NO_DECOMPRESSION 1924 compressed_file = 0; 1925 #endif /* NO_DECOMPRESSION */ 1926 1927 if (!(dirname = setup_part (dirname))) 1928 return 0; 1929 1930 if (*dirname != '/') 1931 errnum = ERR_BAD_FILENAME; 1932 1933 if (fsys_type == NUM_FSYS) 1934 errnum = ERR_FSYS_MOUNT; 1935 1936 if (errnum) 1937 return 0; 1938 1939 /* set "dir" function to list completions */ 1940 print_possibilities = 1; 1941 1942 return (*(fsys_table[fsys_type].dir_func)) (dirname); 1943 } 1944 #endif /* STAGE1_5 */ 1945 1946 void 1947 grub_close (void) 1948 { 1949 #ifndef NO_BLOCK_FILES 1950 if (block_file) 1951 return; 1952 #endif /* NO_BLOCK_FILES */ 1953 1954 if (fsys_table[fsys_type].close_func != 0) 1955 (*(fsys_table[fsys_type].close_func)) (); 1956 } 1957