=== modified file 'doc/kernel.c' --- doc/kernel.c 2010-01-16 16:27:35 +0000 +++ doc/kernel.c 2010-01-16 16:30:52 +0000 @@ -19,9 +19,6 @@ /* Macros. */ -/* Check if the bit BIT in FLAGS is set. */ -#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) - /* Some screen stuff. */ /* The number of columns. */ #define COLUMNS 80 @@ -51,9 +48,10 @@ pointed by ADDR. */ void cmain (unsigned long magic, unsigned long addr) -{ - multiboot_info_t *mbi; - +{ + struct multiboot_tag *tag; + unsigned size; + /* Clear the screen. */ cls (); @@ -64,177 +62,155 @@ return; } - /* Set MBI to the address of the Multiboot information structure. */ - mbi = (multiboot_info_t *) addr; - - /* Print out the flags. */ - printf ("flags = 0x%x\n", (unsigned) mbi->flags); - - /* Are mem_* valid? */ - if (CHECK_FLAG (mbi->flags, 0)) - printf ("mem_lower = %uKB, mem_upper = %uKB\n", - (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); - - /* Is boot_device valid? */ - if (CHECK_FLAG (mbi->flags, 1)) - printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device); - - /* Is the command line passed? */ - if (CHECK_FLAG (mbi->flags, 2)) - printf ("cmdline = %s\n", (char *) mbi->cmdline); - - /* Are mods_* valid? */ - if (CHECK_FLAG (mbi->flags, 3)) - { - multiboot_module_t *mod; - int i; - - printf ("mods_count = %d, mods_addr = 0x%x\n", - (int) mbi->mods_count, (int) mbi->mods_addr); - for (i = 0, mod = (multiboot_module_t *) mbi->mods_addr; - i < mbi->mods_count; - i++, mod++) - printf (" mod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n", - (unsigned) mod->mod_start, - (unsigned) mod->mod_end, - (char *) mod->cmdline); - } - - /* Bits 4 and 5 are mutually exclusive! */ - if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) - { - printf ("Both bits 4 and 5 are set.\n"); - return; - } - - /* Is the symbol table of a.out valid? */ - if (CHECK_FLAG (mbi->flags, 4)) - { - multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); - - printf ("multiboot_aout_symbol_table: tabsize = 0x%0x, " - "strsize = 0x%x, addr = 0x%x\n", - (unsigned) multiboot_aout_sym->tabsize, - (unsigned) multiboot_aout_sym->strsize, - (unsigned) multiboot_aout_sym->addr); - } - - /* Is the section header table of ELF valid? */ - if (CHECK_FLAG (mbi->flags, 5)) - { - multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); - - printf ("multiboot_elf_sec: num = %u, size = 0x%x," - " addr = 0x%x, shndx = 0x%x\n", - (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, - (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); - } - - /* Are mmap_* valid? */ - if (CHECK_FLAG (mbi->flags, 6)) - { - multiboot_memory_map_t *mmap; - - printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n", - (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); - for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr; - (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; - mmap = (multiboot_memory_map_t *) ((unsigned long) mmap - + mmap->size + sizeof (mmap->size))) - printf (" size = 0x%x, base_addr = 0x%x%x," - " length = 0x%x%x, type = 0x%x\n", - (unsigned) mmap->size, - (unsigned) (mmap->addr >> 32), - (unsigned) (mmap->addr & 0xffffffff), - (unsigned) (mmap->len >> 32), - (unsigned) (mmap->len & 0xffffffff), - (unsigned) mmap->type); - } - - /* Draw diagonal blue line. */ - if (CHECK_FLAG (mbi->flags, 12)) - { - multiboot_uint32_t color; - unsigned i; - void *fb = (void *) (unsigned long) mbi->framebuffer_addr; - - switch (mbi->framebuffer_type) + size = *(unsigned *) addr; + printf ("Announced mbi size 0x%x\n", size); + for (tag = (struct multiboot_tag *) (addr + 4); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + tag->size)) + { + printf ("Tag 0x%x, Size 0x%x\n", tag->type, tag->size); + switch (tag->type) { - case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: - { - unsigned best_distance, distance; - struct multiboot_color *palette; - - palette = (struct multiboot_color *) mbi->framebuffer_palette_addr; - - color = 0; - best_distance = 4*256*256; - - for (i = 0; i < mbi->framebuffer_palette_num_colors; i++) - { - distance = (0xff - palette[i].blue) * (0xff - palette[i].blue) - + palette[i].red * palette[i].red - + palette[i].green * palette[i].green; - if (distance < best_distance) + case MULTIBOOT_TAG_TYPE_CMDLINE: + printf ("Command line = %s\n", + ((struct multiboot_tag_string *) tag)->string); + break; + case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: + printf ("Boot loader name = %s\n", + ((struct multiboot_tag_string *) tag)->string); + break; + case MULTIBOOT_TAG_TYPE_MODULE: + printf ("Module at 0x%x-0x%x. Command line %s\n", + ((struct multiboot_tag_module *) tag)->mod_start, + ((struct multiboot_tag_module *) tag)->mod_end, + ((struct multiboot_tag_module *) tag)->cmdline); + break; + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + printf ("mem_lower = %uKB, mem_upper = %uKB\n", + ((struct multiboot_tag_basic_meminfo *) tag)->mem_lower, + ((struct multiboot_tag_basic_meminfo *) tag)->mem_upper); + break; + case MULTIBOOT_TAG_TYPE_BOOTDEV: + printf ("Boot device 0x%x,%u,%u\n", + ((struct multiboot_tag_bootdev *) tag)->biosdev, + ((struct multiboot_tag_bootdev *) tag)->slice, + ((struct multiboot_tag_bootdev *) tag)->part); + break; + case MULTIBOOT_TAG_TYPE_MMAP: + { + multiboot_memory_map_t *mmap; + + printf ("mmap\n"); + + for (mmap = ((struct multiboot_tag_mmap *) tag)->entries; + (multiboot_uint8_t *) mmap + < (multiboot_uint8_t *) tag + tag->size; + mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + + mmap->size + + sizeof (mmap->size))) + printf (" size = 0x%x, base_addr = 0x%x%x," + " length = 0x%x%x, type = 0x%x\n", + (unsigned) mmap->size, + (unsigned) (mmap->addr >> 32), + (unsigned) (mmap->addr & 0xffffffff), + (unsigned) (mmap->len >> 32), + (unsigned) (mmap->len & 0xffffffff), + (unsigned) mmap->type); + } + break; + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + multiboot_uint32_t color; + unsigned i; + struct multiboot_tag_framebuffer *tagfb + = (struct multiboot_tag_framebuffer *) tag; + void *fb = (void *) (unsigned long) tagfb->common.framebuffer_addr; + + switch (tagfb->common.framebuffer_type) + { + case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: + { + unsigned best_distance, distance; + struct multiboot_color *palette; + + palette = tagfb->framebuffer_palette; + + color = 0; + best_distance = 4*256*256; + + for (i = 0; i < tagfb->framebuffer_palette_num_colors; i++) + { + distance = (0xff - palette[i].blue) + * (0xff - palette[i].blue) + + palette[i].red * palette[i].red + + palette[i].green * palette[i].green; + if (distance < best_distance) + { + color = i; + best_distance = distance; + } + } + } + break; + + case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: + color = ((1 << tagfb->framebuffer_blue_mask_size) - 1) + << tagfb->framebuffer_blue_field_position; + break; + + case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: + color = '\\' | 0x0100; + break; + + default: + color = 0xffffffff; + break; + } + + for (i = 0; i < tagfb->common.framebuffer_width + && i < tagfb->common.framebuffer_height; i++) + { + switch (tagfb->common.framebuffer_bpp) { - color = i; - best_distance = distance; + case 8: + { + multiboot_uint8_t *pixel = fb + + tagfb->common.framebuffer_pitch * i + i; + *pixel = color; + } + break; + case 15: + case 16: + { + multiboot_uint16_t *pixel + = fb + tagfb->common.framebuffer_pitch * i + 2 * i; + *pixel = color; + } + break; + case 24: + { + multiboot_uint32_t *pixel + = fb + tagfb->common.framebuffer_pitch * i + 3 * i; + *pixel = (color & 0xffffff) | (*pixel & 0xff000000); + } + break; + + case 32: + { + multiboot_uint32_t *pixel + = fb + tagfb->common.framebuffer_pitch * i + 4 * i; + *pixel = color; + } + break; } } + break; } - break; - - case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: - color = ((1 << mbi->framebuffer_blue_mask_size) - 1) - << mbi->framebuffer_blue_field_position; - break; - - case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: - color = '\\' | 0x0100; - break; - - default: - color = 0xffffffff; - break; - } - for (i = 0; i < mbi->framebuffer_width - && i < mbi->framebuffer_height; i++) - { - switch (mbi->framebuffer_bpp) - { - case 8: - { - multiboot_uint8_t *pixel = fb + mbi->framebuffer_pitch * i + i; - *pixel = color; - } - break; - case 15: - case 16: - { - multiboot_uint16_t *pixel - = fb + mbi->framebuffer_pitch * i + 2 * i; - *pixel = color; - } - break; - case 24: - { - multiboot_uint32_t *pixel - = fb + mbi->framebuffer_pitch * i + 3 * i; - *pixel = (color & 0xffffff) | (*pixel & 0xff000000); - } - break; - - case 32: - { - multiboot_uint32_t *pixel - = fb + mbi->framebuffer_pitch * i + 4 * i; - *pixel = color; - } - break; - } + } } - + tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + tag->size); + printf ("Total mbi size 0x%x\n", (unsigned) tag - addr); } /* Clear the screen and initialize VIDEO, XPOS and YPOS. */ === modified file 'doc/multiboot.texi' --- doc/multiboot.texi 2010-01-16 16:27:35 +0000 +++ doc/multiboot.texi 2010-01-16 16:33:54 +0000 @@ -514,7 +514,7 @@ @table @samp @item EAX -Must contain the magic value @samp{0x2BADB002}; the presence of this +Must contain the magic value @samp{0x36d76289}; the presence of this value indicates to the operating system that it was loaded by a Multiboot-compliant boot loader (e.g. as opposed to another type of boot loader that the operating system can also be loaded from). @@ -577,9 +577,8 @@ @node Boot information format -@section Boot information format - -FIXME: Split this chapter like the chapter ``OS image format''. +@section Boot information +@subsection Boot information format Upon entry to the operating system, the @code{EBX} register contains the physical address of a @dfn{Multiboot information} data structure, @@ -594,206 +593,167 @@ operating system's responsibility to avoid overwriting this memory until it is done using it. -The format of the Multiboot information structure (as defined so far) -follows: - -@example -@group - +-------------------+ -0 | flags | (required) - +-------------------+ -4 | mem_lower | (present if flags[0] is set) -8 | mem_upper | (present if flags[0] is set) - +-------------------+ -12 | boot_device | (present if flags[1] is set) - +-------------------+ -16 | cmdline | (present if flags[2] is set) - +-------------------+ -20 | mods_count | (present if flags[3] is set) -24 | mods_addr | (present if flags[3] is set) - +-------------------+ -28 - 40 | syms | (present if flags[4] or - | | flags[5] is set) - +-------------------+ -44 | mmap_length | (present if flags[6] is set) -48 | mmap_addr | (present if flags[6] 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) - +-------------------+ -64 | boot_loader_name | (present if flags[9] is set) - +-------------------+ -68 | apm_table | (present if flags[10] is set) - +-------------------+ -72 | vbe_control_info | (present if flags[11] is set) -76 | vbe_mode_info | -80 | vbe_mode | -82 | vbe_interface_seg | -84 | vbe_interface_off | -86 | vbe_interface_len | - +-------------------+ -88 | framebuffer_addr | (present if flags[12] is set) -96 | framebuffer_pitch | -100 | framebuffer_width | -104 | framebuffer_height| -108 | framebuffer_bpp | -109 | framebuffer_type | -110-115 | color_info | - +-------------------+ - -@end group -@end example - -The first longword indicates the presence and validity of other fields -in the Multiboot information structure. All as-yet-undefined bits must -be set to zero by the boot loader. Any set bits that the operating -system does not understand should be ignored. Thus, the @samp{flags} -field also functions as a version indicator, allowing the Multiboot -information structure to be expanded in the future without breaking -anything. - -If bit 0 in the @samp{flags} word is set, then the @samp{mem_*} fields -are valid. @samp{mem_lower} and @samp{mem_upper} indicate the amount of +@subsection Basic tags structure +Boot information consists of fixed part and a series of tags. Fixed part is as following: +@example +@group + +-------------------+ +0-3 | total_size | + +-------------------+ +@end group +@end example + +@samp{total_size} contains the total size of boot information including +this field and terminating tag in bytes + +Every tag begins with following fields: + +@example +@group + +-------------------+ +0 | type | +4-7 | size | + +-------------------+ +@end group +@end example + +@samp{type} contains an identifier of contents of the rest of the tag. +@samp{size} contains the size of tag including header fields. +Tags follow one another without any gaps. Tags are terminated by a tag of type @samp{0} and size @samp{8}. + +@subsection Basic memory information +@example +@group + +-------------------+ +0 | type = 4 | +4 | size = 16 | +8 | mem_lower | +12-15 | mem_upper | + +-------------------+ +@end group +@end example + + @samp{mem_lower} and @samp{mem_upper} indicate the amount of lower and upper memory, respectively, in kilobytes. Lower memory starts at address 0, and upper memory starts at address 1 megabyte. The maximum possible value for lower memory is 640 kilobytes. The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte. It is not guaranteed to be this value. -If bit 1 in the @samp{flags} word is set, then the @samp{boot_device} -field is valid, and indicates which @sc{bios} disk device the boot +@subsection BIOS Boot device +@example +@group + +-------------------+ +0 | type = 5 | +4 | size = 20 | +8 | biosdev | +12 | partition | +16-19 | sub_parition | + +-------------------+ +@end group +@end example + +This tag indicates which @sc{bios} disk device the boot loader loaded the OS image from. If the OS image was not loaded from a -@sc{bios} disk, then this field must not be present (bit 3 must be -clear). The operating system may use this field as a hint for -determining its own @dfn{root} device, but is not required to. The -@samp{boot_device} field is laid out in four one-byte subfields as -follows: - -@example -@group -+-------+-------+-------+-------+ -| part3 | part2 | part1 | drive | -+-------+-------+-------+-------+ -@end group -@end example - -The first byte contains the @sc{bios} drive number as understood by the +@sc{bios} disk, then this tag must not be present. The operating system may +use this field as a hint for determining its own @dfn{root} device, +but is not required to. + +The @samp{biosdev} contains the @sc{bios} drive number as understood by the @sc{bios} INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy disk or 0x80 for the first hard disk. -The three remaining bytes specify the boot partition. @samp{part1} -specifies the @dfn{top-level} partition number, @samp{part2} specifies a +The three remaining bytes specify the boot partition. @samp{partition} +specifies the @dfn{top-level} partition number, @samp{sub_partition} specifies a @dfn{sub-partition} in the top-level partition, etc. Partition numbers -always start from zero. Unused partition bytes must be set to 0xFF. For +always start from zero. Unused partition bytes must be set to 0xFFFFFFFF. For example, if the disk is partitioned using a simple one-level DOS -partitioning scheme, then @samp{part1} contains the DOS partition -number, and @samp{part2} and @samp{part3} are both 0xFF. As another +partitioning scheme, then @samp{partition} contains the DOS partition +number, and @samp{sub_partition} if 0xFFFFFF. As another example, if a disk is partitioned first into DOS partitions, and then one of those DOS partitions is subdivided into several BSD partitions -using BSD's @dfn{disklabel} strategy, then @samp{part1} contains the DOS -partition number, @samp{part2} contains the BSD sub-partition within -that DOS partition, and @samp{part3} is 0xFF. +using BSD's @dfn{disklabel} strategy, then @samp{partition} contains the DOS +partition number and @samp{sub_partition} contains the BSD sub-partition within +that DOS partition. DOS extended partitions are indicated as partition numbers starting from 4 and increasing, rather than as nested sub-partitions, even though the underlying disk layout of extended partitions is hierarchical in nature. For example, if the boot loader boots from the second extended partition on a disk partitioned in conventional DOS style, then -@samp{part1} will be 5, and @samp{part2} and @samp{part3} will both be -0xFF. - -If bit 2 of the @samp{flags} longword is set, the @samp{cmdline} field -is valid, and contains the physical address of the command line to -be passed to the kernel. The command line is a normal C-style -zero-terminated string. - -If bit 3 of the @samp{flags} is set, then the @samp{mods} fields -indicate to the kernel what boot modules were loaded along with the -kernel image, and where they can be found. @samp{mods_count} contains -the number of modules loaded; @samp{mods_addr} contains the physical -address of the first module structure. @samp{mods_count} may be zero, -indicating no boot modules were loaded, even if bit 1 of @samp{flags} is -set. Each module structure is formatted as follows: - -@example -@group - +-------------------+ -0 | mod_start | -4 | mod_end | - +-------------------+ -8 | string | - +-------------------+ -12 | reserved (0) | - +-------------------+ -@end group -@end example - -The first two fields contain the start and end addresses of the boot +@samp{partition} will be 5, and @samp{sub_partiton} will be 0xFFFFFFFF. + + +@subsection Boot command line +@example +@group + +-------------------+ +0 | type = 1 | +4 | size | +8-xx | string | + +-------------------+ +@end group +@end example + +@samp{string} contains command line. The command line is a normal C-styl +zero-terminated UTF-8 string padded to have length divisible by 4. + +@subsection Modules +@example +@group + +-------------------+ +0 | type = 3 | +4 | size | +8 | mod_start | +12 | mod_end | +16-xx | string | + +-------------------+ +@end group +@end example + +This tag indicates to the kernel what boot module was loaded along with the +kernel image, and where it can be found. + +The @samp{mod_start} and @samp{mod_end} contain the start and end addresses of the boot module itself. The @samp{string} field provides an arbitrary string to be associated with that particular boot module; it is a zero-terminated -ASCII string, just like the kernel command line. The @samp{string} field -may be 0 if there is no string associated with the module. Typically the +UTF-8 string, just like the kernel command line. Typically the string might be a command line (e.g. if the operating system treats boot modules as executable programs), or a pathname (e.g. if the operating system treats boot modules as files in a file system), but its exact use -is specific to the operating system. The @samp{reserved} field must be -set to 0 by the boot loader and ignored by the operating system. - -@strong{Caution:} Bits 4 & 5 are mutually exclusive. - -If bit 4 in the @samp{flags} word is set, then the following fields in -the Multiboot information structure starting at byte 28 are valid: - -@example -@group - +-------------------+ -28 | tabsize | -32 | strsize | -36 | addr | -40 | reserved (0) | - +-------------------+ -@end group -@end example - -These indicate where the symbol table from an a.out kernel image can be -found. @samp{addr} is the physical address of the size (4-byte unsigned -long) of an array of a.out format @dfn{nlist} structures, followed -immediately by the array itself, then the size (4-byte unsigned long) of -a set of zero-terminated @sc{ascii} strings (plus sizeof(unsigned long) in -this case), and finally the set of strings itself. @samp{tabsize} is -equal to its size parameter (found at the beginning of the symbol -section), and @samp{strsize} is equal to its size parameter (found at -the beginning of the string section) of the following string table to -which the symbol table refers. Note that @samp{tabsize} may be 0, -indicating no symbols, even if bit 4 in the @samp{flags} word is set. - +is specific to the operating system. + +Tag is padded in the way to have size divisible by 4. + +One tag appears per module. This tag type may appear multiple times. + +@subsection ELF-Symbols If bit 5 in the @samp{flags} word is set, then the following fields in the Multiboot information structure starting at byte 28 are valid: @example @group +-------------------+ -28 | num | -32 | size | -36 | addr | -40 | shndx | +0 | type = 9 | +4 | size | +8 | num | +12 | entsize | +16 | shndx | +20-xx | section headers | +-------------------+ @end group @end example -These indicate where the section header table from an ELF kernel is, the +This tag contains section header table from an ELF kernel, the size of each entry, number of entries, and the string table used as the index of names. They correspond to the @samp{shdr_*} entries (@samp{shdr_num}, etc.) in the Executable and Linkable Format (@sc{elf}) specification in the program header. All sections are loaded, and the physical address fields of the @sc{elf} section header then refer to where the sections are in memory (refer to the i386 @sc{elf} documentation for -details as to how to read the section header(s)). Note that -@samp{shdr_num} may be 0, indicating no symbols, even if bit 5 in the -@samp{flags} word is set. +details as to how to read the section header(s)). +@subsection Memory map If bit 6 in the @samp{flags} word is set, then the @samp{mmap_*} fields are valid, and indicate the address and length of a buffer containing a memory map of the machine provided by the @sc{bios}. @samp{mmap_addr} is @@ -823,86 +783,52 @@ The map provided is guaranteed to list all standard @sc{ram} that should 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 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: - +The corresponding tag is @example @group +-------------------+ -0 | size | - +-------------------+ -4 | drive_number | - +-------------------+ -5 | drive_mode | - +-------------------+ -6 | drive_cylinders | -8 | drive_heads | -9 | drive_sectors | - +-------------------+ -10 - xx | drive_ports | +0 | type = 6 | +4 | size | +8-xx | entries | +-------------------+ @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: - -@table @samp -@item 0 -CHS mode (traditional cylinder/head/sector addressing mode). - -@item 1 -LBA mode (Logical Block Addressing mode). -@end table - -The three fields, @samp{drive_cylinders}, @samp{drive_heads} and -@samp{drive_sectors}, indicate the geometry of the drive detected by the -@sc{bios}. @samp{drive_cylinders} contains the number of the -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 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 -returned by the @dfn{GET CONFIGURATION} @sc{bios} call. If the @sc{bios} -call fails, then the size of the table must be @emph{zero}. - +@subsection Boot loader name If bit 9 in the @samp{flags} is set, the @samp{boot_loader_name} field is valid, and contains the physical address of the name of a boot loader booting the kernel. The name is a normal C-style zero-terminated string. -If bit 10 in the @samp{flags} is set, the @samp{apm_table} field is -valid, and contains the physical address of an @sc{apm} table defined as -below: - +Corresponding tag is: +@example +@group + +-------------------+ +0 | type = 2 | +4 | size | +8-xx | string | + +-------------------+ +@end group +@end example + +@samp{string} contains zero-terminated UTF-8 string padded to have length divisible by 4. + +@subsection APM table +The tag type 10 contains @sc{apm} table @example @group +----------------------+ -0 | version | -2 | cseg | -4 | offset | -8 | cseg_16 | -10 | dseg | -12 | flags | -14 | cseg_len | -16 | cseg_16_len | -18 | dseg_len | +0 | type = 10 | +4 | size | +8 | version | +10 | cseg | +12 | offset | +16 | cseg_16 | +18 | dseg | +20 | flags | +22 | cseg_len | +24 | cseg_16_len | +26-27 | dseg_len | +----------------------+ @end group @end example @@ -919,10 +845,24 @@ @uref{http://www.microsoft.com/hwdev/busbios/amp_12.htm, Advanced Power Management (APM) BIOS Interface Specification}, for more information. -If bit 11 in the @samp{flags} is set, the @sc{vbe} table is available. +@subsection VBE info +@example +@group + +-------------------+ +0 | type = 7 | +4 | size = 784 | +8 | vbe_mode | +10 | vbe_interface_seg | +12 | vbe_interface_off | +14 | vbe_interface_len | +16 | vbe_control_info | +528-783 | vbe_mode_info | + +-------------------+ +@end group +@end example The fields @samp{vbe_control_info} and @samp{vbe_mode_info} contain -the physical addresses of @sc{vbe} control information returned by the +@sc{vbe} control information returned by the @sc{vbe} Function 00h and @sc{vbe} mode information returned by the @sc{vbe} Function 01h, respectively. @@ -937,62 +877,61 @@ use the new protected mode interface, you will have to find the table yourself. -The fields for the graphics table are designed for @sc{vbe}, but -Multiboot boot loaders may simulate @sc{vbe} on non-@sc{vbe} modes, as -if they were @sc{vbe} modes. - -If bit 12 in the @samp{flags} is set, the @sc{Framebuffer} table is available. - -The field @samp{framebuffer_addr} contains framebuffer physical address. This -field is 64-bit wide but bootloader @dfn{should} set it under 4 GiB if possible -for compatibility with kernels which aren't aware of PAE or AMD64. The field -@samp{framebuffer_pitch} contains the framebuffer pitch in bytes. The fields -@samp{framebuffer_width}, @samp{framebuffer_height} contain the framebuffer -dimensions in pixels. The field @samp{framebuffer_bpp} contains the number of -bits per pixel. If @samp{framebuffer_type} is set to @samp{0} it means -indexed color will be used. In this case color_info is defined as follows: -@example -@group - +----------------------------------+ -110 | framebuffer_palette_addr | -114 | framebuffer_palette_num_colors | - +----------------------------------+ -@end group -@end example -@samp{framebuffer_palette_addr} contains the address of the color palette, -which is an array of color descriptors. Each color descriptor has the -following structure: +@subsection Framebuffer info +@example +@group + +--------------------+ +0 | type = 8 | +4 | size | +8 | framebuffer_addr | +16 | framebuffer_pitch | +20 | framebuffer_width | +24 | framebuffer_height | +28 | framebuffer_bpp | +29 | framebuffer_type | +30 | color_info | + +--------------------+ +@end group +@end example + +The field @samp{framebuffer_addr} contains framebuffer physical address. This field is 64-bit wide but bootloader @dfn{should} set it under 4GiB if possible for compatibility with payloads which aren't aware of PAE or amd64. The field @samp{framebuffer_pitch} contains pitch in bytes. The fields @samp{framebuffer_width}, @samp{framebuffer_height} contain framebuffer dimensions in pixels. The field @samp{framebuffer_bpp} contains number of bits per pixel. If @samp{framebuffer_type} is set to 0 it means indexed color. In this case color_info is defined as follows: +@example +@group + +----------------------------------+ +30 | framebuffer_palette_num_colors | +34-xx | framebuffer_palette | + +----------------------------------+ +@end group +@end example +@samp{framebuffer_palette} is an array of colour descriptors. +Each colour descriptor has following structure: @example @group +-------------+ 0 | red_value | 1 | green_value | -2 | blue_value | +2-2 | blue_value | +-------------+ @end group @end example -If @samp{framebuffer_type} is set to @samp{1} it means direct RGB color will -be used. Then color_type is defined as follows: +If @samp{framebuffer_type} is set to @samp{1} it means direct RGB color. +Then color_type is defined as follows: @example @group - +----------------------------------+ -110 | framebuffer_red_field_position | -111 | framebuffer_red_mask_size | -112 | framebuffer_green_field_position | -113 | framebuffer_green_mask_size | -114 | framebuffer_blue_field_position | -115 | framebuffer_blue_mask_size | - +----------------------------------+ + +----------------------------------+ +30 | framebuffer_red_field_position | +31 | framebuffer_red_mask_size | +32 | framebuffer_green_field_position | +33 | framebuffer_green_mask_size | +34 | framebuffer_blue_field_position | +35-35 | framebuffer_blue_mask_size | + +----------------------------------+ @end group @end example -If @samp{framebuffer_type} is set to @samp{2} it means EGA-standard text mode -will be used. In this case @samp{framebuffer_width} and -@samp{framebuffer_height} are expressed in characters instead of pixels. -@samp{framebuffer_bpp} is equal to 16 (bits per character) and -@samp{framebuffer_pitch} is expressed in bytes per text line. -All further values of @samp{framebuffer_type} are reserved for future expansion. +If @samp{framebuffer_type} is set to @samp{2} it means EGA text. In this case @samp{framebuffer_width} and @samp{framebuffer_height} are expressed in characters and not in pixels. @samp{framebuffer_bpp} is equal 16 (16 bits per character) and @samp{framebuffer_pitch} is expressed in bytes per text line. +All further values of @samp{framebuffer_type} are reserved for future expansion @node Examples @chapter Examples === modified file 'doc/multiboot2.h' --- doc/multiboot2.h 2010-01-16 16:27:35 +0000 +++ doc/multiboot2.h 2010-01-16 16:31:40 +0000 @@ -51,42 +51,17 @@ /* This flag indicates the use of the address fields in the header. */ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 -/* Flags to be set in the 'flags' member of the multiboot info structure. */ - -/* is there basic lower/upper memory information? */ -#define MULTIBOOT_INFO_MEMORY 0x00000001 -/* is there a boot device set? */ -#define MULTIBOOT_INFO_BOOTDEV 0x00000002 -/* is the command-line defined? */ -#define MULTIBOOT_INFO_CMDLINE 0x00000004 -/* are there modules to do something with? */ -#define MULTIBOOT_INFO_MODS 0x00000008 - -/* These next two are mutually exclusive */ - -/* is there a symbol table loaded? */ -#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 -/* is there an ELF section header table? */ -#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 - -/* is there a full memory map? */ -#define MULTIBOOT_INFO_MEM_MAP 0x00000040 - -/* Is there drive info? */ -#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 - -/* Is there a config table? */ -#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 - -/* Is there a boot loader name? */ -#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 - -/* Is there a APM table? */ -#define MULTIBOOT_INFO_APM_TABLE 0x00000400 - -/* Is there video information? */ -#define MULTIBOOT_INFO_VBE_INFO 0x00000800 -#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 #ifndef ASM_FILE @@ -120,26 +95,6 @@ multiboot_uint32_t depth; }; -/* The symbol table for a.out. */ -struct multiboot_aout_symbol_table -{ - multiboot_uint32_t tabsize; - multiboot_uint32_t strsize; - multiboot_uint32_t addr; - multiboot_uint32_t reserved; -}; -typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; - -/* The section header table for ELF. */ -struct multiboot_elf_section_header_table -{ - multiboot_uint32_t num; - multiboot_uint32_t size; - multiboot_uint32_t addr; - multiboot_uint32_t shndx; -}; -typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; - struct multiboot_color { multiboot_uint8_t red; @@ -147,75 +102,114 @@ multiboot_uint8_t blue; }; -struct multiboot_info -{ - /* Multiboot info version number */ - multiboot_uint32_t flags; - - /* Available memory from BIOS */ +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; multiboot_uint32_t mem_lower; multiboot_uint32_t mem_upper; - - /* "root" partition */ - multiboot_uint32_t boot_device; - - /* Kernel command line */ - multiboot_uint32_t cmdline; - - /* Boot-Module list */ - multiboot_uint32_t mods_count; - multiboot_uint32_t mods_addr; - - union - { - multiboot_aout_symbol_table_t aout_sym; - multiboot_elf_section_header_table_t elf_sec; - } u; - - /* Memory Mapping buffer */ - multiboot_uint32_t mmap_length; - multiboot_uint32_t mmap_addr; - - /* Drive Info buffer */ - multiboot_uint32_t drives_length; - multiboot_uint32_t drives_addr; - - /* ROM configuration table */ - multiboot_uint32_t config_table; - - /* Boot Loader Name */ - multiboot_uint32_t boot_loader_name; - - /* APM table */ - multiboot_uint32_t apm_table; - - /* Video */ - multiboot_uint32_t vbe_control_info; - multiboot_uint32_t vbe_mode_info; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t vbe_mode; multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t framebuffer_addr; multiboot_uint32_t framebuffer_pitch; multiboot_uint32_t framebuffer_width; multiboot_uint32_t framebuffer_height; multiboot_uint8_t framebuffer_bpp; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 multiboot_uint8_t framebuffer_type; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + union { - /* Indexed color. */ struct { - struct multiboot_color *framebuffer_palette_addr; multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; }; - - /* Direct RGB color. */ struct { multiboot_uint8_t framebuffer_red_field_position; @@ -227,32 +221,31 @@ }; }; }; -typedef struct multiboot_info multiboot_info_t; - -struct multiboot_mmap_entry -{ - multiboot_uint32_t size; - multiboot_uint64_t addr; - multiboot_uint64_t len; -#define MULTIBOOT_MEMORY_AVAILABLE 1 -#define MULTIBOOT_MEMORY_RESERVED 2 - multiboot_uint32_t type; -} __attribute__((packed)); -typedef struct multiboot_mmap_entry multiboot_memory_map_t; - -struct multiboot_mod_list -{ - /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; - - /* Module command line */ - multiboot_uint32_t cmdline; - - /* padding to take it to 16 bytes (must be zero) */ - multiboot_uint32_t pad; -}; -typedef struct multiboot_mod_list multiboot_module_t; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; #endif /* ! ASM_FILE */