change the format of drive info in the Multiboot Specification, implement some of the new features.

This commit is contained in:
okuji 2000-10-15 21:18:14 +00:00
parent 636299cc50
commit 11236082ea
9 changed files with 277 additions and 89 deletions

View file

@ -1,3 +1,31 @@
2000-10-16 OKUJI Yoshinori <okuji@gnu.org>
Some of the new Multiboot features are supported. APM support
and VESA support are not strictly defined or implemented yet.
* docs/multiboot.texi (Top): Increase the version number.
(Boot information format): Changed the drive information format,
because it was not straightforward.
* grub/asmstub.c (io_map): New variable.
(track_int13): New function.
(get_rom_config_table): Likewise.
* stage2/stage2.c (cmain): Set CONFIG_ENTRIES to MBI.DRIVES_ADDR
+ MBI.DRIVES.LENGTH instead of MBI.MMAP_ADDR + MBI.MMAP_LENGTH.
* stage2/common.c (init_bios_info) [!STAGE1_5]: Added support
for drive info, ROM config table, and boot loader name features
of the Multiboot Specification.
* stage2/mb_info.h (drive_info): New structure.
(MB_DI_CHS_MODE): New macro.
(MB_DI_LBA_MODE): Likewise.
(multiboot_info): Added drives_length, drives_addr,
config_table, and boot_loader_name.
(MB_INFO_DRIVE_INFO): New macro.
(MB_INFO_CONFIG_TABLE): Likewise.
(MB_INFO_BOOT_LOADER_NAME): Likewise.
* stage2/asm.S (get_rom_config_table): New function.
* stage2/shared.h (get_rom_config_table): Declared.
2000-10-16 OKUJI Yoshinori <okuji@gnu.org>
* util/grub-install.in (convert): Check only if the file exists,

View file

@ -22,8 +22,11 @@ instead of the root directory.
use FILE as the grub shell.
.TP
\fB\-\-force\-lba\fR
Force GRUB to use LBA mode even for a buggy
force GRUB to use LBA mode even for a buggy
BIOS.
.TP
\fB\-\-recheck\fR
probe a device map even if it already exists.
.PP
INSTALL_DEVICE can be a GRUB device name or a system device filename.
.PP

View file

@ -71,7 +71,7 @@ into another language, under the above conditions for modified versions.
@top Multiboot Specification
This file documents Multiboot Specification, the proposal for the boot
sequence standard. This edition documents version 0.6.90.
sequence standard. This edition documents version 0.6.91.
@end ifnottex
@ -567,7 +567,7 @@ follows:
44 | mmap_length | (present if flags[6] is set)
48 | mmap_addr | (present if flags[6] is set)
+-------------------+
52 | drives_count | (present if flags[7] is set)
52 | drives_length | (present if flags[7] is set)
56 | drives_addr | (present if flags[7] is set)
+-------------------+
60 | config_table | (present if flags[8] is set)
@ -765,29 +765,33 @@ be available for normal use.
If bit 7 in the @samp{flags} is set, then the @samp{drives_*} fields
are valid, and indicate the address of the physical address of the first
drive structure and the number of drive structures. @samp{drives_addr}
is the address, and @samp{drives_count} is the
number. @samp{drives_count} may be zero. Each drive structure is
formatted as follows:
drive structure and the size of drive structures. @samp{drives_addr}
is the address, and @samp{drives_length} is the total size of drive
structures. Note that @samp{drives_length} may be zero. Each drive
structure is formatted as follows:
@example
@group
+-------------------+
0 | drive_number |
0 | size |
+-------------------+
1 | drive_mode |
4 | drive_number |
+-------------------+
2 | drive_cylinders |
4 | drive_heads |
5 | drive_sectors |
5 | drive_mode |
+-------------------+
6 | drive_ports |
6 | drive_cylinders |
8 | drive_heads |
9 | drive_sectors |
+-------------------+
10 | reserved (0) |
10 - xx | drive_ports |
+-------------------+
@end group
@end example
The @samp{size} field specifies the size of this structure. The size
varies, depending on the number of ports. Note that the size may not be
equal to (10 + 2 * the number of ports), because of an alignment.
The @samp{drive_number} field contains the BIOS drive number. The
@samp{drive_mode} field represents the access mode used by the boot
loader. Currently, the following modes are defined:
@ -807,15 +811,11 @@ cylinders. @samp{drive_heads} contains the number of the
heads. @samp{drive_sectors} contains the number of the sectors per
track.
The @samp{drive_ports} field contains the physical address of the array
of the I/O ports used for the drive in the @sc{bios} code. The array
consists of zero or more unsigned two-bytes integers, and is terminated
with zero. Note that the array may contain any number of I/O ports that
are not related to the drive actually (such as @sc{dma} controller's
ports).
The last field @samp{reserved} is reserved for future use, and must be
zero. The size is four bytes.
The @samp{drive_ports} field contains the array of the I/O ports used
for the drive in the @sc{bios} code. The array consists of zero or more
unsigned two-bytes integers, and is terminated with zero. Note that the
array may contain any number of I/O ports that are not related to the
drive actually (such as @sc{dma} controller's ports).
If bit 8 in the @samp{flags} is set, then the @samp{config_table} field
is valid, and indicates the address of the @sc{rom} configuration table

View file

@ -71,6 +71,7 @@ int saved_entryno = 0;
char version_string[] = VERSION;
char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */
unsigned long linux_text_len = 0;
unsigned short io_map[IO_MAP_SIZE];
/* Emulation requirements. */
char *grub_scratch_mem = 0;
@ -423,6 +424,19 @@ get_mmap_entry (struct mmar_desc *desc, int cont)
return 0;
}
/* Track the int13 handler. */
void
track_int13 (int drive)
{
/* Nothing to do in the simulator. */
}
/* Get the ROM configuration table. */
unsigned long
get_rom_config_table (void)
{
return 0;
}
/* low-level timing info */
int

View file

@ -1596,6 +1596,50 @@ xsmap:
pop %ebp
ret
/*
* get_rom_config_table()
*
* Get the linear address of a ROM configuration table. Return zero,
* if fails.
*/
ENTRY(get_rom_config_table)
pushl %ebp
pushl %ebx
/* zero %ebx for simplicity */
xorl %ebx, %ebx
call EXT_C(prot_to_real)
.code16
movw $0xc0, %ax
int $0x15
jc no_rom_table
testb %ah, %ah
jnz no_rom_table
movw %es, %dx
jmp found_rom_table
no_rom_table:
xorw %dx, %dx
xorw %bx, %bx
found_rom_table:
DATA32 call EXT_C(real_to_prot)
.code32
/* compute the linear address */
movw %dx, %ax
shll $4, %eax
addl %ebx, %eax
popl %ebx
popl %ebp
ret
/*
* gateA20(int linear)
*

View file

@ -158,6 +158,7 @@ init_bios_info (void)
{
#ifndef STAGE1_5
unsigned long cont, memtmp, addr;
int drive;
#endif
/*
@ -260,11 +261,60 @@ init_bios_info (void)
saved_mem_upper = mbi.mem_upper;
/* Get the drive info. */
/* FIXME: This should be postponed until a Multiboot kernel actually
requires it, because this could slow down the start-up
unreasonably. */
mbi.drives_length = 0;
mbi.drives_addr = addr;
/* For now, GRUB doesn't probe floppies, since it is trivial to map
floppy drives to BIOS drives. */
for (drive = 0x80; drive < 0x88; drive++)
{
struct geometry geom;
struct drive_info *info = (struct drive_info *) addr;
unsigned short *port;
/* Get the geometry. This ensures that the drive is present. */
if (get_diskinfo (drive, &geom))
break;
/* Clean out the I/O map. */
grub_memset ((char *) io_map, 0,
IO_MAP_SIZE * sizeof (unsigned short));
/* Track the int13 handler. */
track_int13 (drive);
/* Set the information. */
info->drive_number = drive;
info->drive_mode = ((geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
? MB_DI_LBA_MODE : MB_DI_CHS_MODE);
info->drive_cylinders = geom.cylinders;
info->drive_heads = geom.heads;
info->drive_sectors = geom.sectors;
addr += sizeof (struct drive_info);
for (port = io_map; *port; port++, addr += sizeof (unsigned short))
*((unsigned short *) addr) = *port;
info->size = addr - (unsigned long) info;
mbi.drives_length += info->size;
}
/* Get the ROM configuration table by INT 15, AH=C0h. */
mbi.config_table = get_rom_config_table ();
/* Set the boot loader name. */
mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
/*
* Initialize other Multiboot Info flags.
*/
mbi.flags = MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV;
mbi.flags = (MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV
| MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE
| MB_INFO_BOOT_LOADER_NAME);
#endif /* STAGE1_5 */

View file

@ -23,17 +23,17 @@
*/
struct mod_list
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
unsigned long mod_start;
unsigned long mod_end;
/* Module command line */
unsigned long cmdline;
/* padding to take it to 16 bytes (must be zero) */
unsigned long pad;
};
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
unsigned long mod_start;
unsigned long mod_end;
/* Module command line */
unsigned long cmdline;
/* padding to take it to 16 bytes (must be zero) */
unsigned long pad;
};
/*
@ -44,19 +44,45 @@ struct mod_list
*/
struct AddrRangeDesc
{
unsigned long size;
unsigned long long BaseAddr;
unsigned long long Length;
unsigned long Type;
/* unspecified optional padding... */
};
{
unsigned long size;
unsigned long long BaseAddr;
unsigned long long Length;
unsigned long Type;
/* unspecified optional padding... */
};
/* usable memory "Type", all others are reserved. */
#define MB_ARD_MEMORY 1
/* Drive Info structure. */
struct drive_info
{
/* The size of this structure. */
unsigned long size;
/* The BIOS drive number. */
unsigned char drive_number;
/* The access mode (see below). */
unsigned char drive_mode;
/* The BIOS geometry. */
unsigned short drive_cylinders;
unsigned char drive_heads;
unsigned char drive_sectors;
/* The array of I/O ports used for the drive. */
unsigned short drive_ports[0];
};
/* Drive Mode. */
#define MB_DI_CHS_MODE 0
#define MB_DI_LBA_MODE 1
/*
* MultiBoot Info description
*
@ -65,52 +91,62 @@ struct AddrRangeDesc
*/
struct multiboot_info
{
/* MultiBoot info version number */
unsigned long flags;
/* Available memory from BIOS */
unsigned long mem_lower;
unsigned long mem_upper;
/* "root" partition */
unsigned long boot_device;
/* Kernel command line */
unsigned long cmdline;
/* Boot-Module list */
unsigned long mods_count;
unsigned long mods_addr;
union
{
/* MultiBoot info version number */
unsigned long flags;
/* Available memory from BIOS */
unsigned long mem_lower;
unsigned long mem_upper;
/* "root" partition */
unsigned long boot_device;
/* Kernel command line */
unsigned long cmdline;
/* Boot-Module list */
unsigned long mods_count;
unsigned long mods_addr;
union
{
struct
{
/* (a.out) Kernel symbol table info */
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long pad;
}
a;
struct
{
/* (ELF) Kernel section header table */
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
}
e;
}
syms;
/* Memory Mapping buffer */
unsigned long mmap_length;
unsigned long mmap_addr;
};
struct
{
/* (a.out) Kernel symbol table info */
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long pad;
}
a;
struct
{
/* (ELF) Kernel section header table */
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
}
e;
}
syms;
/* Memory Mapping buffer */
unsigned long mmap_length;
unsigned long mmap_addr;
/* Drive Info buffer */
unsigned long drives_length;
unsigned long drives_addr;
/* ROM configuration table */
unsigned long config_table;
/* Boot Loader Name */
unsigned long boot_loader_name;
};
/*
* Flags to be set in the 'flags' parameter above
@ -135,6 +171,15 @@ struct multiboot_info
/* is there a full memory map? */
#define MB_INFO_MEM_MAP 0x40
/* Is there drive info? */
#define MB_INFO_DRIVE_INFO 0x80
/* Is there a config table? */
#define MB_INFO_CONFIG_TABLE 0x100
/* Is there a boot loader name? */
#define MB_INFO_BOOT_LOADER_NAME 0x200
/*
* The following value must be present in the EAX register.
*/

View file

@ -643,6 +643,10 @@ int get_eisamemsize (void);
map). */
int get_mmap_entry (struct mmar_desc *desc, int cont);
/* Get the linear address of a ROM configuration table. Return zero,
if fails. */
unsigned long get_rom_config_table (void);
/* Return the data area immediately following our code. */
int get_code_end (void);

View file

@ -797,7 +797,7 @@ cmain (void)
config_len = 0;
menu_len = 0;
num_entries = 0;
config_entries = (char *) (mbi.mmap_addr + mbi.mmap_length);
config_entries = (char *) mbi.drives_addr + mbi.drives_length;
menu_entries = (char *) MENU_BUF;
init_config ();