1 /* @r{kernel.c - the C part of the kernel} */
2 /* @r{Copyright (C) 1999 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */
18 #include <multiboot.h>
22 /* @r{Check if the bit BIT in FLAGS is set.} */
23 #define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
25 /* @r{Some screen stuff.} */
26 /* @r{The number of columns.} */
28 /* @r{The number of lines.} */
30 /* @r{The attribute of an character.} */
32 /* @r{The video memory address.} */
36 /* @r{Save the X position.} */
38 /* @r{Save the Y position.} */
40 /* @r{Point to the video memory.} */
41 static volatile unsigned char *video;
43 /* @r{Forward declarations.} */
44 void cmain (unsigned long magic, unsigned long addr);
45 static void cls (void);
46 static void itoa (char *buf, int base, int d);
47 static void putchar (int c);
48 void printf (const char *format, ...);
50 /* @r{Check if MAGIC is valid and print the Multiboot information structure
53 cmain (unsigned long magic, unsigned long addr)
55 multiboot_info_t *mbi;
57 /* @r{Clear the screen.} */
60 /* @r{Am I booted by a Multiboot-compliant boot loader?} */
61 if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
63 printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
67 /* @r{Set MBI to the address of the Multiboot information structure.} */
68 mbi = (multiboot_info_t *) addr;
70 /* @r{Print out the flags.} */
71 printf ("flags = 0x%x\n", (unsigned) mbi->flags);
73 /* @r{Are mem_* valid?} */
74 if (CHECK_FLAG (mbi->flags, 0))
75 printf ("mem_lower = %uKB, mem_upper = %uKB\n",
76 (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
78 /* @r{Is boot_device valid?} */
79 if (CHECK_FLAG (mbi->flags, 1))
80 printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
82 /* @r{Is the command line passed?} */
83 if (CHECK_FLAG (mbi->flags, 2))
84 printf ("cmdline = %s\n", (char *) mbi->cmdline);
86 /* @r{Are mods_* valid?} */
87 if (CHECK_FLAG (mbi->flags, 3))
92 printf ("mods_count = %d, mods_addr = 0x%x\n",
93 (int) mbi->mods_count, (int) mbi->mods_addr);
94 for (i = 0, mod = (module_t *) mbi->mods_addr;
97 printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
98 (unsigned) mod->mod_start,
99 (unsigned) mod->mod_end,
100 (char *) mod->string);
103 /* @r{Bits 4 and 5 are mutually exclusive!} */
104 if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
106 printf ("Both bits 4 and 5 are set.\n");
110 /* @r{Is the symbol table of a.out valid?} */
111 if (CHECK_FLAG (mbi->flags, 4))
113 aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
115 printf ("aout_symbol_table: tabsize = 0x%0x, "
116 "strsize = 0x%x, addr = 0x%x\n",
117 (unsigned) aout_sym->tabsize,
118 (unsigned) aout_sym->strsize,
119 (unsigned) aout_sym->addr);
122 /* @r{Is the section header table of ELF valid?} */
123 if (CHECK_FLAG (mbi->flags, 5))
125 elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
127 printf ("elf_sec: num = %u, size = 0x%x,"
128 " addr = 0x%x, shndx = 0x%x\n",
129 (unsigned) elf_sec->num, (unsigned) elf_sec->size,
130 (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
133 /* @r{Are mmap_* valid?} */
134 if (CHECK_FLAG (mbi->flags, 6))
138 printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
139 (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
140 for (mmap = (memory_map_t *) mbi->mmap_addr;
141 (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
142 mmap = (memory_map_t *) ((unsigned long) mmap
143 + mmap->size + sizeof (mmap->size)))
144 printf (" size = 0x%x, base_addr = 0x%x%x,"
145 " length = 0x%x%x, type = 0x%x\n",
146 (unsigned) mmap->size,
147 (unsigned) mmap->base_addr_high,
148 (unsigned) mmap->base_addr_low,
149 (unsigned) mmap->length_high,
150 (unsigned) mmap->length_low,
151 (unsigned) mmap->type);
155 /* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */
161 video = (unsigned char *) VIDEO;
163 for (i = 0; i < COLUMNS * LINES * 2; i++)
170 /* @r{Convert the integer D to a string and save the string in BUF. If
171 BASE is equal to 'd', interpret that D is decimal, and if BASE is
172 equal to 'x', interpret that D is hexadecimal.} */
174 itoa (char *buf, int base, int d)
178 unsigned long ud = d;
181 /* @r{If %d is specified and D is minus, put `-' in the head.} */
182 if (base == 'd' && d < 0)
188 else if (base == 'x')
191 /* @r{Divide UD by DIVISOR until UD == 0.} */
194 int remainder = ud % divisor;
196 *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
198 while (ud /= divisor);
200 /* @r{Terminate BUF.} */
203 /* @r{Reverse BUF.} */
216 /* @r{Put the character C on the screen.} */
220 if (c == '\n' || c == '\r')
230 *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
231 *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
238 /* @r{Format a string and print it on the screen, just like the libc
241 printf (const char *format, ...)
243 char **arg = (char **) &format;
249 while ((c = *format++) != 0)
263 itoa (buf, c, *((int *) arg++));
279 putchar (*((int *) arg++));