Index: grub2-x86/multiboot/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ grub2-x86/multiboot/Makefile 2006-11-13 17:32:20.000000000 -0600 @@ -0,0 +1,13 @@ +CFLAGS := -nostdinc -I. +LDFLAGS := -nostdlib -Ttext=0x00100000 +ASFLAGS := -I. + +OBJS := boot.o kernel.o + +all: multiboot + +multiboot: $(OBJS) + $(CC) $(LDFLAGS) $^ -o $@ + +clean: + rm -f $(OBJS) multiboot Index: grub2-x86/multiboot/boot.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ grub2-x86/multiboot/boot.S 2006-11-13 18:56:52.000000000 -0600 @@ -0,0 +1,93 @@ +/* boot.S - bootstrap the kernel */ +/* Copyright (C) 1999, 2001 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_FILE 1 +#include "multiboot.h" + +/* XXX why does EXT_C exist? */ +#define EXT_C(sym) sym + +/* The size of our stack (16KB). */ +#define STACK_SIZE 0x4000 + +/* The flags for the Multiboot header. */ +#ifdef __ELF__ +# define MULTIBOOT_HEADER_FLAGS 0x00000003 +#else +# define MULTIBOOT_HEADER_FLAGS 0x00010003 +#endif + + .text + + .globl start, _start +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) +#ifndef __ELF__ + /* header_addr */ + .long multiboot_header + /* load_addr */ + .long _start + /* load_end_addr */ + .long _edata + /* bss_end_addr */ + .long _end + /* entry_addr */ + .long multiboot_entry +#endif /* ! __ELF__ */ + +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(mb_printf) + +loop: hlt + jmp loop + +halt_message: + .asciz "Halted." + + /* Our stack area. */ + .comm stack, STACK_SIZE + Index: grub2-x86/multiboot/kernel.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ grub2-x86/multiboot/kernel.c 2006-11-13 18:56:40.000000000 -0600 @@ -0,0 +1,248 @@ +/* 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 = (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 mb_putchar (int c); +void mb_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) +{ + struct multiboot_tag_header *tag; + int tagno; + + /* Clear the screen. */ + cls (); + + /* Am I booted by a Multiboot-compliant boot loader? */ + if (magic != MULTIBOOT_BOOTLOADER_MAGIC) + { + mb_printf ("Invalid magic number: 0x%x\n", (unsigned) magic); + return; + } + + tag = (struct multiboot_tag_header *) addr; + if (tag->key != MULTIBOOT_TAG_START) + { + mb_printf ("First tag has invalid key: 0x%x\n", tag->key); + return; + } + + tagno = 0; + do + { + tag = (struct multiboot_tag_header *) ((char *) tag + tag->len); + tagno++; + switch (tag->key) + { + case MULTIBOOT_TAG_START: + mb_printf ("Tag %d is a duplicate START tag\n", tagno); + return; + case MULTIBOOT_TAG_CMDLINE: + { + struct multiboot_tag_cmdline *cmdline = + (struct multiboot_tag_cmdline *) tag; + mb_printf ("cmdline = %s\n", cmdline->cmdline); + } + break; + case MULTIBOOT_TAG_MODULE: + { + struct multiboot_tag_module *module = + (struct multiboot_tag_module *) tag; + mb_printf ("module: addr 0x%x, size 0x%x, cmdline %s\n", + (unsigned int) module->addr, (unsigned int) module->size, + module->cmdline); + } + break; + case MULTIBOOT_TAG_NAME: + { + struct multiboot_tag_name *name = + (struct multiboot_tag_name *) tag; + mb_printf ("bootloader name = %s\n", name->name); + } + break; + case MULTIBOOT_TAG_END: + mb_printf ("end\n"); + break; + default: + mb_printf ("Tag %d has invalid key: 0x%x\n", tagno, tag->key); + return; + } + } + while (tag->key != MULTIBOOT_TAG_END); +} + +/* 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 +mb_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 mb_printf. */ +void +mb_printf (const char *format, ...) +{ + char **arg = (char **) &format; + int c; + char buf[20]; + + arg++; + + while ((c = *format++) != 0) + { + if (c != '%') + mb_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) + mb_putchar (*p++); + break; + + default: + mb_putchar (*((int *) arg++)); + break; + } + } + } +} Index: grub2-x86/multiboot/multiboot.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ grub2-x86/multiboot/multiboot.h 2006-11-13 18:44:57.000000000 -0600 @@ -0,0 +1,136 @@ +/* multiboot.h - multiboot header file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006 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. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_HEADER_SEARCH 8192 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* The bits in the required part of flags field we don't support. */ +#define MULTIBOOT_UNSUPPORTED 0x0000fffc + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* + * Flags set in the 'flags' member of the multiboot header. + */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +#ifndef ASM_FILE + +#include "stdint.h" + +/* XXX not portable? */ +#if __WORDSIZE == 64 +typedef uint64_t multiboot_word; +#else +typedef uint32_t multiboot_word; +#endif + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + uint32_t magic; + + /* Feature flags. */ + uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + uint32_t header_addr; + uint32_t load_addr; + uint32_t load_end_addr; + uint32_t bss_end_addr; + uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + uint32_t mode_type; + uint32_t width; + uint32_t height; + uint32_t depth; +}; + +struct multiboot_tag_header +{ + uint32_t key; + uint32_t len; +}; + +#define MULTIBOOT_TAG_START 0 +struct multiboot_tag_start +{ + struct multiboot_tag_header header; + multiboot_word size; /* Total size of all multiboot tags. */ + multiboot_word num; /* Number of multiboot tags. */ +}; + +#define MULTIBOOT_TAG_CMDLINE 1 +struct multiboot_tag_cmdline +{ + struct multiboot_tag_header header; + char cmdline[1]; +}; + +#define MULTIBOOT_TAG_MODULE 2 +struct multiboot_tag_module +{ + struct multiboot_tag_header header; + multiboot_word addr; + multiboot_word size; + char cmdline[1]; +}; + +#define MULTIBOOT_TAG_NAME 4 +struct multiboot_tag_name +{ + struct multiboot_tag_header header; + char name[1]; +}; + +#define MULTIBOOT_TAG_END 0xffff +struct multiboot_tag_end +{ + struct multiboot_tag_header header; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ Index: grub2-x86/multiboot/stdint.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ grub2-x86/multiboot/stdint.h 2006-11-13 18:55:54.000000000 -0600 @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006 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. + */ + +#ifndef MULTIBOOT_STDINT_H +#define MULTIBOOT_STDINT_H + +typedef unsigned int uint32_t; +typedef unsigned long uint64_t; + +#endif /* ! MULTIBOOT_STDINT_H */