1
/* common.c - miscellaneous shared variables and routines */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
#ifdef SUPPORT_DISKLESS
27
# include <etherboot.h>
31
* Shared BIOS/boot data.
34
struct multiboot_info mbi;
35
unsigned long saved_drive;
36
unsigned long saved_partition;
38
//unsigned long cdrom_drives[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
39
unsigned long cdrom_drive = GRUB_INVALID_DRIVE;
40
unsigned long force_cdrom_as_boot_device = 1;
41
unsigned long ram_drive;
42
unsigned long rd_base = 0; /* Note the rd_base value of -1 invalidates the ram drive. */
43
unsigned long rd_size = 0; /* The rd_size 0 stands for 4GB, not for length of 0. */
44
unsigned long saved_mem_upper;
45
unsigned long saved_mem_lower;
46
unsigned long saved_mmap_addr;
47
unsigned long saved_mmap_length;
50
/* This saves the maximum size of extended memory (in KB). */
51
unsigned long extended_memory;
52
unsigned long init_free_mem_start;
61
grub_error_t errnum = ERR_NONE;
68
[ERR_BAD_ARGUMENT] = "Invalid argument",
69
[ERR_BAD_FILENAME] = "Filename must be either an absolute pathname or blocklist",
70
[ERR_BAD_FILETYPE] = "Bad file or directory type",
71
[ERR_BAD_GZIP_DATA] = "Bad or corrupt data while decompressing file",
72
[ERR_BAD_GZIP_HEADER] = "Bad or incompatible header in compressed file",
73
[ERR_BAD_PART_TABLE] = "Partition table invalid or corrupt",
74
[ERR_BAD_VERSION] = "Mismatched or corrupt version of stage1/stage2",
75
[ERR_BELOW_1MB] = "Loading below 1MB is not supported",
76
[ERR_BOOT_COMMAND] = "Kernel must be loaded before booting",
77
[ERR_BOOT_FAILURE] = "Unknown boot failure",
78
[ERR_BOOT_FEATURES] = "Unsupported Multiboot features requested",
79
[ERR_DEV_FORMAT] = "Unrecognized device string, or you omitted the required DEVICE part which should lead the filename.",
80
[ERR_DEV_NEED_INIT] = "Device not initialized yet",
81
[ERR_DEV_VALUES] = "Invalid device requested",
82
[ERR_EXEC_FORMAT] = "Invalid or unsupported executable format",
83
[ERR_FILELENGTH] = "Filesystem compatibility error, cannot read whole file",
84
[ERR_FILENAME_FORMAT] = "The leading DEVICE of the filename to find must be stripped off,\n\tand DIR for set-root must begin in a slash(/).",
85
[ERR_FILE_NOT_FOUND] = "File not found",
86
[ERR_FSYS_CORRUPT] = "Inconsistent filesystem structure",
87
[ERR_FSYS_MOUNT] = "Cannot mount selected partition",
88
[ERR_GEOM] = "Selected cylinder exceeds maximum supported by BIOS",
89
[ERR_HD_VOL_START_0] = "The BPB hidden_sectors should not be zero for a hard-disk partition boot sector",
90
[ERR_IN_SITU_FLOPPY] = "Only hard drives could be mapped in situ.",
91
[ERR_IN_SITU_MEM] = "Should not use --mem together with --in-situ.",
92
[ERR_NEED_LX_KERNEL] = "Linux kernel must be loaded before initrd",
93
[ERR_NEED_MB_KERNEL] = "Multiboot kernel must be loaded before modules",
94
[ERR_NO_DISK] = "Selected disk does not exist",
95
[ERR_NO_DISK_SPACE] = "No spare sectors on the disk",
96
[ERR_NO_PART] = "No such partition",
97
[ERR_NO_HEADS] = "The number of heads must be specified. The `--heads=0' option tells map to choose a value(but maybe unsuitable) for you",
98
[ERR_NO_SECTORS] = "The number of sectors per track must be specified. The `--sectors-per-track=0' option tells map to choose a value(but maybe unsuitable) for you",
99
[ERR_NON_CONTIGUOUS] = "File for drive emulation must be in one contiguous disk area",
100
[ERR_NUMBER_OVERFLOW] = "Overflow while parsing number",
101
[ERR_NUMBER_PARSING] = "Error while parsing number",
102
[ERR_OUTSIDE_PART] = "Attempt to access block outside partition",
103
[ERR_PRIVILEGED] = "Must be authenticated",
104
[ERR_READ] = "Disk read error",
105
[ERR_SYMLINK_LOOP] = "Too many symbolic links",
106
[ERR_UNALIGNED] = "File is not sector aligned",
107
[ERR_UNRECOGNIZED] = "Unrecognized command",
108
[ERR_WONT_FIT] = "Selected item cannot fit into memory",
109
[ERR_WRITE] = "Disk write error",
110
[ERR_INT13_ON_HOOK] = "The int13 handler already on hook",
111
[ERR_INT13_OFF_HOOK] = "The int13 handler not yet on hook",
112
[ERR_NO_DRIVE_MAPPED] = "Refuse to hook int13 because of empty drive map table",
113
[ERR_INVALID_HEADS] = "Invalid heads. Should be between 0 and 256(0 means auto)",
114
[ERR_INVALID_SECTORS] = "Invalid sectors. Should be between 0 and 63(0 means auto)",
115
[ERR_SPECIFY_GEOM] = "Should not specify geometry when mapping a whole drive or when emulating a hard disk with a logical partition",
116
[ERR_EXTENDED_PARTITION] = "Extended partition table is invalid, or its CHS values conflict with the BPB in a logical partition",
117
[ERR_DEL_MEM_DRIVE] = "You should delete other mem drive first, or use `--mem' option to force the deletion",
118
[ERR_SPECIFY_MEM] = "Should not specify `--mem' when mapping a whole drive",
119
[ERR_SPECIFY_RESTRICTION] = "Options --read-only, --fake-write and --unsafe-boot are mutually exclusive. Should not specify them repeatedly.",
120
[ERR_INVALID_FLOPPIES] = "Invalid floppies. Should be between 0 and 2",
121
[ERR_INVALID_HARDDRIVES] = "Invalid harddrives. Should be between 0 and 127",
122
[ERR_INVALID_LOAD_SEGMENT] = "Invalid load segment. Should be between 0 and 0x9FFF",
123
[ERR_INVALID_LOAD_OFFSET] = "Invalid load offset. Should be between 0 and 0xFFFF",
124
[ERR_INVALID_LOAD_LENGTH] = "Invalid load length. Should be between 512 and 0xA0000",
125
[ERR_INVALID_SKIP_LENGTH] = "Invalid skip length. Should be non-negative and less than the file size",
126
[ERR_INVALID_BOOT_CS] = "Invalid boot CS. Should be between 0 and 0xFFFF",
127
[ERR_INVALID_BOOT_IP] = "Invalid boot IP. Should be between 0 and 0xFFFF",
128
[ERR_INVALID_RAM_DRIVE] = "Invalid ram_drive. Should be between 0 and 254",
129
// [ERR_INVALID_RD_BASE] = "Invalid rd_base. Should not be 0xffffffff",
130
// [ERR_INVALID_RD_SIZE] = "Invalid rd_size. Should not be 0",
131
[ERR_MD_BASE] = "When mapping whole mem device at a fixed location, you must specify --mem to a value > 0.",
132
[ERR_RD_BASE] = "RD_BASE must be sector-aligned and non-zero for mapping at a fixed location",
133
[ERR_DOS_BACKUP] = "GRUB was not booted from DOS, or the backup copy of DOS at physical\naddress 0x200000 is corrupt",
134
[ERR_ENABLE_A20] = "Failed to turn on Gate A20!",
135
[ERR_DISABLE_A20] = "Failed to turn off Gate A20!",
136
[ERR_DEFAULT_FILE] = "Invalid DEFAULT file format. Please copy a valid DEFAULT file from the grub4dos release and try again. Also note that the DEFAULT file must be uncompressed.",
137
[ERR_PARTITION_TABLE_FULL] = "Cannot use --in-situ because the partition table is full(i.e., all the 4 entries are in use).",
138
[ERR_MD5_FORMAT] = "Unrecognized md5 string. You must create it using the MD5CRYPT command.",
143
/* static for BIOS memory map fakery */
144
static struct AddrRangeDesc fakemap[3] =
146
{20, 0, 0, MB_ARD_MEMORY},
147
{20, 0x100000, 0, MB_ARD_MEMORY},
148
{20, 0x1000000, 0, MB_ARD_MEMORY}
151
/* A big problem is that the memory areas aren't guaranteed to be:
152
(1) contiguous, (2) sorted in ascending order, or (3) non-overlapping.
155
mmap_avail_at (unsigned long bottom)
157
unsigned long long top;
164
for (cont = 0, addr = saved_mmap_addr;
165
addr < saved_mmap_addr + saved_mmap_length;
166
addr += *((unsigned long *) addr) + 4)
168
struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr;
170
if (desc->Type == MB_ARD_MEMORY
171
&& desc->BaseAddr <= top
172
&& desc->BaseAddr + desc->Length > top)
174
top = desc->BaseAddr + desc->Length;
181
/* For now, GRUB assumes 32bits addresses, so... */
182
if (top > 0xFFFFFFFF)
185
return (unsigned long) top - bottom;
187
#endif /* ! STAGE1_5 */
189
/* This queries for BIOS information. */
191
init_bios_info (void)
194
unsigned long cont, memtmp, addr;
199
unsigned long force_pxe_as_boot_device;
200
#endif /* ! STAGE1_5 */
201
#endif /* ! GRUB_UTIL */
204
* Get information from BIOS on installed RAM.
209
printf("\rGet lower memory... ");
211
saved_mem_lower = get_memsize (0); /* int12 --------safe enough */
213
printf("\rGet upper memory... ");
215
saved_mem_upper = get_memsize (1); /* int15/88 -----safe enough */
219
* We need to call this somewhere before trying to put data
220
* above 1 MB, since without calling it, address line 20 will be wired
221
* to 0. Not too desirable.
225
debug = debug_boot + 1;
227
printf("\rTurning on gate A20... ");
235
if (gateA20 (1)) /* int15/24 -----safe enough */
237
/* wipe out the messages on success */
239
wait = 0; /* sleep 0 second after A20 control */
241
printf("Failure! Report bug, please!\n");
242
wait = 5; /* sleep 5 second on failure */
245
/* Get current time. */
246
while ((time2 = getrtsecs ()) == 0xFF);
248
for (j = 0; j < 0x00800000; j++)
250
if ((time1 = getrtsecs ()) != time2 && time1 != 0xFF)
261
extern void grub2_gate_a20 (int on);
263
printf("\r \r"); /* wipe out the messages */
268
/* Store the size of extended memory in EXTENDED_MEMORY, in order to
269
tell it to non-Multiboot OSes. */
270
extended_memory = saved_mem_upper;
273
* The MBI.MEM_UPPER variable only recognizes upper memory in the
274
* first memory region. If there are multiple memory regions,
275
* the rest are reported to a Multiboot-compliant OS, but otherwise
279
addr = get_code_end ();
280
saved_mmap_addr = addr;
281
saved_mmap_length = 0;
284
printf("\rGet E820 memory... ");
287
cont = get_mmap_entry ((void *) addr, cont); /* int15/e820 ------ will write memory! */
289
/* If the returned buffer's length is zero, quit. */
290
if (! *((unsigned long *) addr))
293
saved_mmap_length += *((unsigned long *) addr) + 4;
294
addr += *((unsigned long *) addr) + 4;
298
if (! (saved_mmap_length))
299
printf("\rGet E801 memory... ");
301
if (saved_mmap_length)
303
unsigned long long max_addr;
306
* This is to get the lower memory, and upper memory (up to the
307
* first memory hole), into the MBI.MEM_{LOWER,UPPER}
308
* elements. This is for OS's that don't care about the memory
309
* map, but might care about total RAM available.
311
saved_mem_lower = mmap_avail_at (0) >> 10;
312
saved_mem_upper = mmap_avail_at (0x100000) >> 10;
314
/* Find the maximum available address. Ignore any memory holes. */
315
for (max_addr = 0, addr = saved_mmap_addr;
316
addr < saved_mmap_addr + saved_mmap_length;
317
addr += *((unsigned long *) addr) + 4)
319
struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr;
321
if (desc->Type == MB_ARD_MEMORY && desc->Length > 0
322
&& desc->BaseAddr + desc->Length > max_addr)
323
max_addr = desc->BaseAddr + desc->Length;
326
extended_memory = (max_addr - 0x100000) >> 10;
328
else if ((memtmp = get_eisamemsize ()) != -1) /* int15/e801 ------safe enough */
330
cont = memtmp & ~0xFFFF;
331
memtmp = memtmp & 0xFFFF;
334
extended_memory = (cont >> 10) + 0x3c00;
336
extended_memory = memtmp;
338
if (!cont || (memtmp == 0x3c00))
339
memtmp += (cont >> 10);
342
/* XXX should I do this at all ??? */
344
saved_mmap_addr = (unsigned long) fakemap;
345
saved_mmap_length = sizeof (fakemap);
346
fakemap[0].Length = (saved_mem_lower << 10);
347
fakemap[1].Length = (memtmp << 10);
348
fakemap[2].Length = cont;
351
saved_mem_upper = memtmp;
354
printf("\r \r"); /* wipe out the messages */
356
mbi.mem_upper = saved_mem_upper;
357
mbi.mem_lower = saved_mem_lower;
358
mbi.mmap_addr = saved_mmap_addr;
359
mbi.mmap_length = saved_mmap_length;
362
is64bit = check_64bit ();
365
/* Get the drive info. */
366
/* FIXME: This should be postponed until a Multiboot kernel actually
367
requires it, because this could slow down the start-up
369
mbi.drives_length = 0;
370
mbi.drives_addr = addr;
372
/* For now, GRUB doesn't probe floppies, since it is trivial to map
373
floppy drives to BIOS drives. */
375
#define FIND_DRIVES 8
377
#define FIND_DRIVES (*((char *)0x475))
380
grub_printf ("hard drives: %d, int13: %X, int15: %X\n", FIND_DRIVES, *(unsigned long *)0x4C, *(unsigned long *)0x54);
383
for (drive = 0x80; drive < 0x80 + FIND_DRIVES; drive++)
385
struct drive_info *info = (struct drive_info *) addr;
386
// unsigned short *port;
388
/* Get the geometry. This ensures that the drive is present. */
391
grub_printf ("get_diskinfo(%X), ", drive);
393
if (get_diskinfo (drive, &tmp_geom))
397
grub_printf (" %sC/H/S=%d/%d/%d, Sector Count/Size=%d/%d\n",
398
(tmp_geom.flags & BIOSDISK_FLAG_LBA_EXTENSION) ? "LBA, " : "",
399
tmp_geom.cylinders, tmp_geom.heads, tmp_geom.sectors,
400
tmp_geom.total_sectors, tmp_geom.sector_size);
402
/* Set the information. */
403
info->drive_number = drive;
404
info->drive_mode = ((tmp_geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
405
? MB_DI_LBA_MODE : MB_DI_CHS_MODE);
406
info->drive_cylinders = tmp_geom.cylinders;
407
info->drive_heads = tmp_geom.heads;
408
info->drive_sectors = tmp_geom.sectors;
410
addr += sizeof (struct drive_info);
412
info->size = addr - (unsigned long) info;
413
mbi.drives_length += info->size;
416
init_free_mem_start = addr;
421
* Initialize other Multiboot Info flags.
424
mbi.flags = (MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV | MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE | MB_INFO_BOOT_LOADER_NAME);
425
if (saved_mmap_length)
426
mbi.flags |= MB_INFO_MEM_MAP;
428
#endif /* STAGE1_5 */
432
force_pxe_as_boot_device = 0;
433
if (! ((*(char *)0x8205) & 0x01)) /* if it is not disable pxe */
438
PXENV_GET_CACHED_INFO_t get_cached_info;
440
printf("\rbegin pxe scan... ");
446
pxe_basemem = *((unsigned short*)0x413);
448
get_cached_info.PacketType = PXENV_PACKET_TYPE_DHCP_ACK;
449
get_cached_info.Buffer = get_cached_info.BufferSize = 0;
451
printf("\rbegin pxe call(type=DHCP_ACK)... ");
452
pxe_call (PXENV_GET_CACHED_INFO, &get_cached_info);
455
if (get_cached_info.Status)
457
grub_printf ("\nFatal: DHCP_ACK failure!\n");
461
discover_reply = LINEAR(get_cached_info.Buffer);
463
pxe_yip = discover_reply->yip;
464
pxe_sip = discover_reply->sip;
465
pxe_gip = discover_reply->gip;
467
pxe_mac_type = discover_reply->Hardware;
468
pxe_mac_len = discover_reply->Hardlen;
469
grub_memmove (&pxe_mac, &discover_reply->CAddr, pxe_mac_len);
471
get_cached_info.PacketType = PXENV_PACKET_TYPE_CACHED_REPLY;
472
get_cached_info.Buffer = get_cached_info.BufferSize = 0;
474
printf("\rbegin pxe call(type=CACHED_REPLY)... ");
475
pxe_call (PXENV_GET_CACHED_INFO, &get_cached_info);
478
if (get_cached_info.Status)
480
grub_printf ("\nFatal: CACHED_REPLY failure!\n");
490
discover_reply = LINEAR(get_cached_info.Buffer);
492
/* on pxe boot, we only use preset_menu */
493
if (preset_menu != (char*)0x800)
494
preset_menu = (char*)0x800;
497
force_pxe_as_boot_device = 1;
498
if (bios_id != 1) /* if it is not Bochs ... */
499
goto set_root;; /* ... skip cdrom check. */
504
#endif /* STAGE1_5 */
505
#endif /* ! GRUB_UTIL */
507
#if !defined(STAGE1_5) && !defined(GRUB_UTIL)
508
/* Set cdrom drive. */
510
/* Get the geometry. */
512
printf("\rboot drive=%X, ", boot_drive);
513
cdrom_drive = get_cdinfo (boot_drive, &tmp_geom);
514
if (! cdrom_drive || cdrom_drive != boot_drive)
515
cdrom_drive = GRUB_INVALID_DRIVE;
516
if (cdrom_drive == GRUB_INVALID_DRIVE)
518
/* read the first sector of the drive */
519
if (((unsigned char)boot_drive) >= 0x80 + FIND_DRIVES)
521
struct disk_address_packet
523
unsigned char length;
524
unsigned char reserved;
525
unsigned short blocks;
526
unsigned long buffer;
527
unsigned long long block;
529
unsigned char dummy[16];
530
} __attribute__ ((packed)) *dap;
532
dap = (struct disk_address_packet *)0x580;
537
dap->buffer = 0x5F80/*SCRATCHSEG*/ << 16;
540
/* set a known value */
541
grub_memset ((char *)0x5F800, 0xEC, 0x800);
542
biosdisk_int13_extensions (0x4200, (unsigned char)boot_drive, dap);
543
/* see if it is a big sector */
546
for (p = (char *)0x5FA00; p < (char *)0x60000; p++)
548
if ((*p) != (char)0xEC)
550
cdrom_drive = boot_drive;
556
} /* if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION) */
560
printf("%s\n", cdrom_drive == GRUB_INVALID_DRIVE ? "Not CD":"Is CD");
564
#if !defined(STAGE1_5) && !defined(GRUB_UTIL)
566
if (cdrom_drive == GRUB_INVALID_DRIVE)
570
struct drive_parameters *drp = (struct drive_parameters *)0x600;
574
#define FIND_DRIVES 8
576
#define FIND_DRIVES (*((char *)0x475))
578
for (drive = 0xFF; drive >= 0x7F; drive--)
580
if (drive >= 0x80 && drive < 0x80 + FIND_DRIVES)
583
/* Get the geometry. */
585
grub_printf ("\rget_cdinfo(%X),", drive);
586
cdrom_drive = get_cdinfo (drive, &tmp_geom);
592
cdrom_drive = get_cdinfo (drive, &tmp_geom);
593
if (cdrom_drive == drive)
598
cdrom_drive = GRUB_INVALID_DRIVE;
600
/* Some buggy BIOSes will hang at EBIOS `Get Drive Parameters' call
601
* (INT 13h function 48h). So we only do further checks for Bochs.
604
if (bios_id != 1) /* if it is not Bochs ... */
605
continue; /* ... skip and try next drive. */
607
/* When qemu has a cdrom attached but not booted from cdrom, its
608
* `get bootable cdrom status call', the int13/ax=4B01, returns CF=0
609
* but with a wrong `Bootable CD-ROM Specification Packet' as follows:
611
* The first byte(packet size) is 0x13, all the rest bytes are 0's.
613
* So we need to call get_diskinfo() here as a workaround.
615
* (The bug was reported by Jacopo Lazzari. Thanks!)
620
version = check_int13_extensions (drive);
622
if (! (version & 1)) /* not support functions 42h-44h, 47h-48h */
623
continue; /* failure, try next drive. */
625
/* It is safe to clear out DRP. */
626
grub_memset (drp, 0, sizeof (struct drive_parameters));
628
drp->size = sizeof (struct drive_parameters) - 16;
630
err = biosdisk_int13_extensions (0x4800, drive, drp);
631
if (! err && drp->bytes_per_sector == ISO_SECTOR_SIZE)
633
/* Assume it is CDROM. */
637
} /* if (drive >= 0x80) */
639
} /* for (drive = 0x7F; drive < 0xff; drive++) */
640
} /* if (cdrom_drive == GRUB_INVALID_DRIVE) */
643
// if (cdrom_drive != GRUB_INVALID_DRIVE)
645
// /* skip pxe init if booting from cdrom */
646
// *(char *)0x8205 |= 0x01;
650
grub_printf(" cdrom_drive == %X.\n", cdrom_drive);
652
#endif /* ! STAGE1_5 && ! GRUB_UTIL */
654
/* check if the no-emulation-mode bootable cdrom exists. */
656
/* if cdrom_drive is active, we assume it is the boot device */
657
if (saved_entryno == 0 && force_cdrom_as_boot_device)
658
force_cdrom_as_boot_device = 0;
659
if (cdrom_drive != GRUB_INVALID_DRIVE && force_cdrom_as_boot_device)
661
boot_drive = cdrom_drive; /* force it to be the boot drive */
664
if (boot_drive == cdrom_drive)
665
/* force it to be "whole drive" without partition table */
666
install_partition = 0xFFFFFF;
672
if (force_pxe_as_boot_device)
674
boot_drive = PXE_DRIVE;
675
install_partition = 0xFFFFFF;
677
#endif /* ! STAGE1_5 */
678
#endif /* ! GRUB_UTIL */
680
/* Set root drive and partition. */
681
saved_drive = boot_drive;
682
saved_partition = install_partition;
687
if (! atapi_dev_count)
688
min_cdrom_id = (cdrom_drive < 0xE0 && cdrom_drive >= 0xC0) ? 0xE0 : 0xC0;
690
/* if grub.exe is booted as a Linux kernel, check the initrd disk. */
692
/* the real mode zero page(only the beginning 2 sectors, the boot params) is loaded at 0xA00 */
694
/* check the header signature "HdrS" (0x53726448) */
696
ram_drive = 0x7f; /* the default ram_drive is a floppy. */
697
if (*(unsigned long*)(int*)(0xA00 + 0x202) == 0x53726448)
699
unsigned long initrd_addr;
700
unsigned long initrd_size;
702
initrd_addr = *(unsigned long*)(int*)(0xA00 + 0x218);
703
initrd_size = *(unsigned long*)(int*)(0xA00 + 0x21c);
704
if (initrd_addr && initrd_size)
706
rd_base = initrd_addr;
707
rd_size = initrd_size;
709
/* check if there is a partition table */
710
if (*(unsigned short *)(initrd_addr + 0x40) == 0xAA55)
712
if (! probe_mbr ((struct master_and_dos_boot_sector *)initrd_addr, 0, initrd_size, 0))
713
ram_drive = 0xfe; /* partition table is valid, so let it be a harddrive */
715
grub_printf ("\nUnrecognized partition table for RAM DRIVE; assuming floppy. Please rebuild\nit using a Microsoft-compatible FDISK tool, if the INITRD is a hard-disk image.\n");
719
#endif /* ! STAGE1_5 */
720
#endif /* ! GRUB_UTIL */
722
/* Start main routine here. */
724
grub_printf("Starting cmain() ... ");
726
#if !defined(STAGE1_5) && !defined(GRUB_UTIL)
728
#endif /* ! STAGE1_5 && ! GRUB_UTIL */
729
// cmain (); /* moved into asm.S and asmstub.c */