diff --git a/ChangeLog b/ChangeLog index 0e557079e..cb2dd4d5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +1999-10-16 OKUJI Yoshinori + + * 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 * multiboot.texi (BIOS device mapping techniques): New section. diff --git a/docs/Makefile.am b/docs/Makefile.am index 1c885ce8a..300c3ffa9 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -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 diff --git a/docs/Makefile.in b/docs/Makefile.in index edee376c0..7ad8332ee 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -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] diff --git a/docs/boot.S b/docs/boot.S new file mode 100644 index 000000000..989c2d4bc --- /dev/null +++ b/docs/boot.S @@ -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 + + .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 + \ No newline at end of file diff --git a/docs/boot.S.texi b/docs/boot.S.texi new file mode 100644 index 000000000..b54c5235b --- /dev/null +++ b/docs/boot.S.texi @@ -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 + + .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 + \ No newline at end of file diff --git a/docs/kernel.c b/docs/kernel.c new file mode 100644 index 000000000..d7a0e273a --- /dev/null +++ b/docs/kernel.c @@ -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 + +/* 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; + } + } + } +} diff --git a/docs/kernel.c.texi b/docs/kernel.c.texi new file mode 100644 index 000000000..a4539c061 --- /dev/null +++ b/docs/kernel.c.texi @@ -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 + +/* @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; + @} + @} + @} +@} diff --git a/docs/multiboot.h b/docs/multiboot.h new file mode 100644 index 000000000..f8afac909 --- /dev/null +++ b/docs/multiboot.h @@ -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 */ diff --git a/docs/multiboot.h.texi b/docs/multiboot.h.texi new file mode 100644 index 000000000..f2a4f1065 --- /dev/null +++ b/docs/multiboot.h.texi @@ -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} */ diff --git a/docs/multiboot.texi b/docs/multiboot.texi index 6792c28f8..66003be2f 100644 --- a/docs/multiboot.texi +++ b/docs/multiboot.texi @@ -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, diff --git a/docs/src2texi b/docs/src2texi new file mode 100644 index 000000000..9c58c6ecf --- /dev/null +++ b/docs/src2texi @@ -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}