add an example Multiboot kernel.

This commit is contained in:
okuji 1999-10-16 10:30:43 +00:00
parent 0263e922f1
commit ec2469fa84
11 changed files with 1053 additions and 12 deletions

View file

@ -1,3 +1,23 @@
1999-10-16 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* docs/multiboot.texi: Include the example source files of a
Multiboot kernel.
* docs/src2texi: New file.
* docs/boot.S: Likewise.
* docs/multiboot.h: Likewise.
* docs/kernel.c: Likewise.
* docs/boot.S.texi: Likewise.
* docs/multiboot.h.texi: Likewise.
* docs/kernel.c.texi: Likewise.
* docs/Makefile.am (EXAMPLES): New varilable.
(multiboot_TEXINFOS): Likewise.
(SRC2TEXI): Likewise.
(noinst_SCRIPTS): Added $(SRC2TEXI).
(EXTRA_DIST): Added $(EXAMPLES) and $(multiboot_TEXINFOS).
(%.c.texi): New target.
(%.h.texi): Likewise.
(%.S.texi): Likewise.
1999-09-22 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* multiboot.texi (BIOS device mapping techniques): New section.

View file

@ -1,9 +1,22 @@
info_TEXINFOS = grub.texi multiboot.texi
EXAMPLES = boot.S kernel.c multiboot.h
multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
man_MANS = grub.8
HELP2MAN = help2man
noinst_SCRIPTS = $(HELP2MAN)
SRC2TEXI = src2texi
noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS)
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
$(EXAMPLES) $(multiboot_TEXINFOS)
%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
# FIXME: Use this rule until Debian has the new Texinfo.
grub.info: grub.texi

View file

@ -83,11 +83,16 @@ install_sh = @install_sh@
info_TEXINFOS = grub.texi multiboot.texi
EXAMPLES = boot.S kernel.c multiboot.h
multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
man_MANS = grub.8
HELP2MAN = help2man
noinst_SCRIPTS = $(HELP2MAN)
SRC2TEXI = src2texi
noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
$(EXAMPLES) $(multiboot_TEXINFOS)
EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS)
subdir = docs
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
@ -103,8 +108,8 @@ man8dir = $(mandir)/man8
MANS = $(man_MANS)
NROFF = nroff
DIST_COMMON = Makefile.am Makefile.in mdate-sh stamp-vti texinfo.tex \
version.texi
DIST_COMMON = $(multiboot_TEXINFOS) Makefile.am Makefile.in mdate-sh \
stamp-vti texinfo.tex version.texi
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@ -148,8 +153,8 @@ grub.info: grub.texi version.texi
grub.dvi: grub.texi version.texi
multiboot.info: multiboot.texi
multiboot.dvi: multiboot.texi
multiboot.info: multiboot.texi $(multiboot_TEXINFOS)
multiboot.dvi: multiboot.texi $(multiboot_TEXINFOS)
DVIPS = dvips
@ -402,6 +407,15 @@ distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
/bin/sh $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
# FIXME: Use this rule until Debian has the new Texinfo.
grub.info: grub.texi
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]

80
docs/boot.S Normal file
View file

@ -0,0 +1,80 @@
/* boot.S - bootstrap the kernel */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define ASM 1
#include <multiboot.h>
.text
.globl start, _start
/* This entry is not used actually. */
start:
_start:
jmp multiboot_entry
/* Align 32 bits boundary. */
.align 4
/* Multiboot header. */
multiboot_header:
/* magic */
.long MULTIBOOT_HEADER_MAGIC
/* flags */
.long MULTIBOOT_HEADER_FLAGS
/* checksum */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
/* header_addr */
.long multiboot_header
/* load_addr */
.long _start
/* load_end_addr */
.long _edata
/* bss_end_addr */
.long _end
/* entry_addr */
.long multiboot_entry
multiboot_entry:
/* Initialize the stack pointer. */
movl $(stack + STACK_SIZE), %esp
/* Reset EFLAGS. */
pushl $0
popf
/* Push the pointer to the Multiboot information structure. */
pushl %ebx
/* Push the magic value. */
pushl %eax
/* Now enter the C main function... */
call EXT_C(cmain)
/* Halt. */
pushl $halt_message
call EXT_C(printf)
loop: hlt
jmp loop
halt_message:
.asciz "Halted."
/* Our stack area. */
.comm stack, STACK_SIZE

80
docs/boot.S.texi Normal file
View file

@ -0,0 +1,80 @@
/* @r{boot.S - bootstrap the kernel} */
/* @r{Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */
#define ASM 1
#include <multiboot.h>
.text
.globl start, _start
/* @r{This entry is not used actually.} */
start:
_start:
jmp multiboot_entry
/* @r{Align 32 bits boundary.} */
.align 4
/* @r{Multiboot header.} */
multiboot_header:
/* @r{magic} */
.long MULTIBOOT_HEADER_MAGIC
/* @r{flags} */
.long MULTIBOOT_HEADER_FLAGS
/* @r{checksum} */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
/* @r{header_addr} */
.long multiboot_header
/* @r{load_addr} */
.long _start
/* @r{load_end_addr} */
.long _edata
/* @r{bss_end_addr} */
.long _end
/* @r{entry_addr} */
.long multiboot_entry
multiboot_entry:
/* @r{Initialize the stack pointer.} */
movl $(stack + STACK_SIZE), %esp
/* @r{Reset EFLAGS.} */
pushl $0
popf
/* @r{Push the pointer to the Multiboot information structure.} */
pushl %ebx
/* @r{Push the magic value.} */
pushl %eax
/* @r{Now enter the C main function...} */
call EXT_C(cmain)
/* @r{Halt.} */
pushl $halt_message
call EXT_C(printf)
loop: hlt
jmp loop
halt_message:
.asciz "Halted."
/* @r{Our stack area.} */
.comm stack, STACK_SIZE

274
docs/kernel.c Normal file
View file

@ -0,0 +1,274 @@
/* kernel.c - the C part of the kernel */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <multiboot.h>
/* 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
/* The number of lines. */
#define LINES 24
/* The attribute of an character. */
#define ATTRIBUTE 7
/* The video memory address. */
#define VIDEO 0xB8000
/* Variables. */
/* Save the X position. */
static int xpos;
/* Save the Y position. */
static int ypos;
/* Point to the video memory. */
static volatile unsigned char *video;
/* Forward declarations. */
void cmain (unsigned long magic, unsigned long addr);
static void cls (void);
static void itoa (char *buf, int base, int d);
static void putchar (int c);
void printf (const char *format, ...);
/* Check if MAGIC is valid and print the Multiboot information structure
pointed by ADDR. */
void
cmain (unsigned long magic, unsigned long addr)
{
multiboot_info_t *mbi;
/* Clear the screen. */
cls ();
/* Am I booted by a Multiboot-compliant boot loader? */
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
printf ("Invalid magic number: 0x%x\n", magic);
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", mbi->flags);
/* Are mem_* valid? */
if (CHECK_FLAG (mbi->flags, 0))
printf ("mem_lower = %dKB, mem_upper = %dKB\n",
mbi->mem_lower, mbi->mem_upper);
/* Is boot_device valid? */
if (CHECK_FLAG (mbi->flags, 1))
printf ("boot_device = 0x%x\n", 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))
{
module_t *mod;
int i;
printf ("mods_count = %d, mods_addr = 0x%x\n",
mbi->mods_count, mbi->mods_addr);
for (i = 0, mod = (module_t *) mbi->mods_addr;
i < mbi->mods_count;
i++, mod += sizeof (module_t))
printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
mod->mod_start, mod->mod_end, (char *) mod->string);
}
/* 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))
{
aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
printf ("aout_symbol_table: tabsize = 0x%0x, "
"strsize = 0x%x, addr = 0x%x\n",
aout_sym->tabsize, aout_sym->strsize, aout_sym->addr);
}
/* Is the section header table of ELF valid? */
if (CHECK_FLAG (mbi->flags, 5))
{
elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
printf ("elf_sec: num = %d, size = 0x%x, addr = 0x%x, shndx = 0x%x\n",
elf_sec->num, elf_sec->size, elf_sec->addr, elf_sec->shndx);
}
/* Are mmap_* valid? */
if (CHECK_FLAG (mbi->flags, 6))
{
memory_map_t *mmap;
printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
mbi->mmap_addr, mbi->mmap_length);
for (mmap = (memory_map_t *) mbi->mmap_addr;
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
mmap = (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",
mmap->size, mmap->base_addr_high, mmap->base_addr_low,
mmap->length_high, mmap->length_low, mmap->type);
}
}
/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
static void
cls (void)
{
int i;
video = (unsigned char *) VIDEO;
for (i = 0; i < COLUMNS * LINES * 2; i++)
*(video + i) = 0;
xpos = 0;
ypos = 0;
}
/* Convert the integer D to a string and save the string in BUF. If
BASE is equal to 'd', interpret that D is decimal, and if BASE is
equal to 'x', interpret that D is hexadecimal. */
static void
itoa (char *buf, int base, int d)
{
char *p = buf;
char *p1, *p2;
unsigned long ud = d;
int divisor = 10;
/* If %d is specified and D is minus, put `-' in the head. */
if (base == 'd' && d < 0)
{
*p++ = '-';
buf++;
ud = -d;
}
else if (base == 'x')
divisor = 16;
/* Divide UD by DIVISOR until UD == 0. */
do
{
int remainder = ud % divisor;
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
}
while (ud /= divisor);
/* Terminate BUF. */
*p = 0;
/* Reverse BUF. */
p1 = buf;
p2 = p - 1;
while (p1 < p2)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
}
}
/* Put the character C on the screen. */
static void
putchar (int c)
{
if (c == '\n' || c == '\r')
{
newline:
xpos = 0;
ypos++;
if (ypos >= LINES)
ypos = 0;
return;
}
*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
xpos++;
if (xpos >= COLUMNS)
goto newline;
}
/* Format a string and print it on the screen, just like the libc
function printf. */
void
printf (const char *format, ...)
{
char **arg = (char **) &format;
int c;
char buf[20];
arg++;
while ((c = *format++) != 0)
{
if (c != '%')
putchar (c);
else
{
char *p;
c = *format++;
switch (c)
{
case 'd':
case 'u':
case 'x':
itoa (buf, c, *((int *) arg++));
p = buf;
goto string;
break;
case 's':
p = *arg++;
if (! p)
p = "(null)";
string:
while (*p)
putchar (*p++);
break;
default:
putchar (*((int *) arg++));
break;
}
}
}
}

274
docs/kernel.c.texi Normal file
View file

@ -0,0 +1,274 @@
/* @r{kernel.c - the C part of the kernel} */
/* @r{Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */
#include <multiboot.h>
/* @r{Macros.} */
/* @r{Check if the bit BIT in FLAGS is set.} */
#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
/* @r{Some screen stuff.} */
/* @r{The number of columns.} */
#define COLUMNS 80
/* @r{The number of lines.} */
#define LINES 24
/* @r{The attribute of an character.} */
#define ATTRIBUTE 7
/* @r{The video memory address.} */
#define VIDEO 0xB8000
/* @r{Variables.} */
/* @r{Save the X position.} */
static int xpos;
/* @r{Save the Y position.} */
static int ypos;
/* @r{Point to the video memory.} */
static volatile unsigned char *video;
/* @r{Forward declarations.} */
void cmain (unsigned long magic, unsigned long addr);
static void cls (void);
static void itoa (char *buf, int base, int d);
static void putchar (int c);
void printf (const char *format, ...);
/* @r{Check if MAGIC is valid and print the Multiboot information structure
pointed by ADDR.} */
void
cmain (unsigned long magic, unsigned long addr)
@{
multiboot_info_t *mbi;
/* @r{Clear the screen.} */
cls ();
/* @r{Am I booted by a Multiboot-compliant boot loader?} */
if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
@{
printf ("Invalid magic number: 0x%x\n", magic);
return;
@}
/* @r{Set MBI to the address of the Multiboot information structure.} */
mbi = (multiboot_info_t *) addr;
/* @r{Print out the flags.} */
printf ("flags = 0x%x\n", mbi->flags);
/* @r{Are mem_* valid?} */
if (CHECK_FLAG (mbi->flags, 0))
printf ("mem_lower = %dKB, mem_upper = %dKB\n",
mbi->mem_lower, mbi->mem_upper);
/* @r{Is boot_device valid?} */
if (CHECK_FLAG (mbi->flags, 1))
printf ("boot_device = 0x%x\n", mbi->boot_device);
/* @r{Is the command line passed?} */
if (CHECK_FLAG (mbi->flags, 2))
printf ("cmdline = %s\n", (char *) mbi->cmdline);
/* @r{Are mods_* valid?} */
if (CHECK_FLAG (mbi->flags, 3))
@{
module_t *mod;
int i;
printf ("mods_count = %d, mods_addr = 0x%x\n",
mbi->mods_count, mbi->mods_addr);
for (i = 0, mod = (module_t *) mbi->mods_addr;
i < mbi->mods_count;
i++, mod += sizeof (module_t))
printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
mod->mod_start, mod->mod_end, (char *) mod->string);
@}
/* @r{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;
@}
/* @r{Is the symbol table of a.out valid?} */
if (CHECK_FLAG (mbi->flags, 4))
@{
aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
printf ("aout_symbol_table: tabsize = 0x%0x, "
"strsize = 0x%x, addr = 0x%x\n",
aout_sym->tabsize, aout_sym->strsize, aout_sym->addr);
@}
/* @r{Is the section header table of ELF valid?} */
if (CHECK_FLAG (mbi->flags, 5))
@{
elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
printf ("elf_sec: num = %d, size = 0x%x, addr = 0x%x, shndx = 0x%x\n",
elf_sec->num, elf_sec->size, elf_sec->addr, elf_sec->shndx);
@}
/* @r{Are mmap_* valid?} */
if (CHECK_FLAG (mbi->flags, 6))
@{
memory_map_t *mmap;
printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
mbi->mmap_addr, mbi->mmap_length);
for (mmap = (memory_map_t *) mbi->mmap_addr;
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
mmap = (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",
mmap->size, mmap->base_addr_high, mmap->base_addr_low,
mmap->length_high, mmap->length_low, mmap->type);
@}
@}
/* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */
static void
cls (void)
@{
int i;
video = (unsigned char *) VIDEO;
for (i = 0; i < COLUMNS * LINES * 2; i++)
*(video + i) = 0;
xpos = 0;
ypos = 0;
@}
/* @r{Convert the integer D to a string and save the string in BUF. If
BASE is equal to 'd', interpret that D is decimal, and if BASE is
equal to 'x', interpret that D is hexadecimal.} */
static void
itoa (char *buf, int base, int d)
@{
char *p = buf;
char *p1, *p2;
unsigned long ud = d;
int divisor = 10;
/* @r{If %d is specified and D is minus, put `-' in the head.} */
if (base == 'd' && d < 0)
@{
*p++ = '-';
buf++;
ud = -d;
@}
else if (base == 'x')
divisor = 16;
/* @r{Divide UD by DIVISOR until UD == 0.} */
do
@{
int remainder = ud % divisor;
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
@}
while (ud /= divisor);
/* @r{Terminate BUF.} */
*p = 0;
/* @r{Reverse BUF.} */
p1 = buf;
p2 = p - 1;
while (p1 < p2)
@{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
@}
@}
/* @r{Put the character C on the screen.} */
static void
putchar (int c)
@{
if (c == '\n' || c == '\r')
@{
newline:
xpos = 0;
ypos++;
if (ypos >= LINES)
ypos = 0;
return;
@}
*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
xpos++;
if (xpos >= COLUMNS)
goto newline;
@}
/* @r{Format a string and print it on the screen, just like the libc
function printf.} */
void
printf (const char *format, ...)
@{
char **arg = (char **) &format;
int c;
char buf[20];
arg++;
while ((c = *format++) != 0)
@{
if (c != '%')
putchar (c);
else
@{
char *p;
c = *format++;
switch (c)
@{
case 'd':
case 'u':
case 'x':
itoa (buf, c, *((int *) arg++));
p = buf;
goto string;
break;
case 's':
p = *arg++;
if (! p)
p = "(null)";
string:
while (*p)
putchar (*p++);
break;
default:
putchar (*((int *) arg++));
break;
@}
@}
@}
@}

115
docs/multiboot.h Normal file
View file

@ -0,0 +1,115 @@
/* multiboot.h - the header for Multiboot */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Macros. */
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* The flags for the Multiboot header. */
#define MULTIBOOT_HEADER_FLAGS 0x00010003
/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/* The size of our stack (16KB). */
#define STACK_SIZE 0x4000
/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym) _ ## sym
#else
# define EXT_C(sym) sym
#endif
#ifndef ASM
/* Do not include here in boot.S. */
/* Types. */
/* The Multiboot header. */
typedef struct multiboot_header
{
unsigned long magic;
unsigned long flags;
unsigned long checksum;
unsigned long header_addr;
unsigned long load_addr;
unsigned long load_end_addr;
unsigned long bss_end_addr;
unsigned long entry_addr;
} multiboot_header_t;
/* The symbol table for a.out. */
typedef struct aout_symbol_table
{
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long reserved;
} aout_symbol_table_t;
/* The section header table for ELF. */
typedef struct elf_section_header_table
{
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
} elf_section_header_table_t;
/* The Multiboot information. */
typedef struct multiboot_info
{
unsigned long flags;
unsigned long mem_lower;
unsigned long mem_upper;
unsigned long boot_device;
unsigned long cmdline;
unsigned long mods_count;
unsigned long mods_addr;
union
{
aout_symbol_table_t aout_sym;
elf_section_header_table_t elf_sec;
} u;
unsigned long mmap_length;
unsigned long mmap_addr;
} multiboot_info_t;
/* The module structure. */
typedef struct module
{
unsigned long mod_start;
unsigned long mod_end;
unsigned long string;
unsigned long reserved;
} module_t;
/* The memory map. Be careful that the offset 0 is base_addr_low
but no size. */
typedef struct memory_map
{
unsigned long size;
unsigned long base_addr_low;
unsigned long base_addr_high;
unsigned long length_low;
unsigned long length_high;
unsigned long type;
} memory_map_t;
#endif /* ! ASM */

115
docs/multiboot.h.texi Normal file
View file

@ -0,0 +1,115 @@
/* @r{multiboot.h - the header for Multiboot} */
/* @r{Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */
/* @r{Macros.} */
/* @r{The magic number for the Multiboot header.} */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* @r{The flags for the Multiboot header.} */
#define MULTIBOOT_HEADER_FLAGS 0x00010003
/* @r{The magic number passed by a Multiboot-compliant boot loader.} */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/* @r{The size of our stack (16KB).} */
#define STACK_SIZE 0x4000
/* @r{C symbol format. HAVE_ASM_USCORE is defined by configure.} */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym) _ ## sym
#else
# define EXT_C(sym) sym
#endif
#ifndef ASM
/* @r{Do not include here in boot.S.} */
/* @r{Types.} */
/* @r{The Multiboot header.} */
typedef struct multiboot_header
@{
unsigned long magic;
unsigned long flags;
unsigned long checksum;
unsigned long header_addr;
unsigned long load_addr;
unsigned long load_end_addr;
unsigned long bss_end_addr;
unsigned long entry_addr;
@} multiboot_header_t;
/* @r{The symbol table for a.out.} */
typedef struct aout_symbol_table
@{
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long reserved;
@} aout_symbol_table_t;
/* @r{The section header table for ELF.} */
typedef struct elf_section_header_table
@{
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
@} elf_section_header_table_t;
/* @r{The Multiboot information.} */
typedef struct multiboot_info
@{
unsigned long flags;
unsigned long mem_lower;
unsigned long mem_upper;
unsigned long boot_device;
unsigned long cmdline;
unsigned long mods_count;
unsigned long mods_addr;
union
@{
aout_symbol_table_t aout_sym;
elf_section_header_table_t elf_sec;
@} u;
unsigned long mmap_length;
unsigned long mmap_addr;
@} multiboot_info_t;
/* @r{The module structure.} */
typedef struct module
@{
unsigned long mod_start;
unsigned long mod_end;
unsigned long string;
unsigned long reserved;
@} module_t;
/* @r{The memory map. Be careful that the offset 0 is base_addr_low
but no size.} */
typedef struct memory_map
@{
unsigned long size;
unsigned long base_addr_low;
unsigned long base_addr_high;
unsigned long length_low;
unsigned long length_high;
unsigned long type;
@} memory_map_t;
#endif /* @r{! ASM} */

View file

@ -865,9 +865,8 @@ In this distribution, the example Multiboot kernel @file{kernel} is
included. The kernel just prints out the Multiboot information structure
on the screen, so you can make use of the kernel to test a
Multiboot-compliant boot loader and for reference to how to implement a
Multiboot kernel. The image and the source files can be found in the
data directory (usually, @file{/usr/share/multiboot} or
@file{/usr/local/share/multiboot}).
Multiboot kernel. The source files can be found under the directory
@file{docs} in the GRUB distribution.
The kernel @file{kernel} consists of only three files: @file{boot.S},
@file{kernel.c} and @file{multiboot.h}. The assembly source
@ -883,7 +882,48 @@ which checks if the magic number passed by the boot loader is valid and
so on, and some functions to print messages on the screen. The file
@file{multiboot.h} defines some macros, such as the magic number for the
Multiboot header, the Multiboot header structure and the Multiboot
information structure. See the source files for more information.
information structure.
@menu
* multiboot.h::
* boot.S::
* kernel.c::
* Other Multiboot kernels::
@end menu
@node multiboot.h
@subsection multiboot.h
This is the source code in the file @file{multiboot.h}:
@example
@include multiboot.h.texi
@end example
@node boot.S
@subsection boot.S
In the file @file{boot.S}:
@example
@include boot.S.texi
@end example
@node kernel.c
@subsection kernel.c
And, in the file @file{kernel.c}:
@example
@include kernel.c.texi
@end example
@node Other Multiboot kernels
@subsection Other Multiboot kernels
Other useful information should be available in Multiboot kernels, such
as GNU Mach and Fiasco @url{http://os.inf.tu-dresden.de/fiasco/}. And,

16
docs/src2texi Normal file
View file

@ -0,0 +1,16 @@
#!/bin/sh
#
# Convert a source file to a TeXinfo file. Stolen from glibc.
#
# Usage: src2texi SRCDIR SRC TEXI
dir=$1
src=`basename $2`
texi=`basename $3`
sed -e 's,[{}],@&,g' \
-e 's,/\*\(@.*\)\*/,\1,g' \
-e 's,/\* *,/* @r{,g' -e 's, *\*/,} */,' \
-e 's/\(@[a-z][a-z]*\)@{\([^}]*\)@}/\1{\2}/g' \
${dir}/${src} | expand > ${texi}.new
mv -f ${texi}.new ${dir}/${texi}