1/* @r{kernel.c - the C part of the kernel} */ 2/* @r{Copyright (C) 1999 Free Software Foundation, Inc. 3 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. 8 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. 13 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.} */ 17 18#include <multiboot.h> 19 20/* @r{Macros.} */ 21 22/* @r{Check if the bit BIT in FLAGS is set.} */ 23#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) 24 25/* @r{Some screen stuff.} */ 26/* @r{The number of columns.} */ 27#define COLUMNS 80 28/* @r{The number of lines.} */ 29#define LINES 24 30/* @r{The attribute of an character.} */ 31#define ATTRIBUTE 7 32/* @r{The video memory address.} */ 33#define VIDEO 0xB8000 34 35/* @r{Variables.} */ 36/* @r{Save the X position.} */ 37static int xpos; 38/* @r{Save the Y position.} */ 39static int ypos; 40/* @r{Point to the video memory.} */ 41static volatile unsigned char *video; 42 43/* @r{Forward declarations.} */ 44void cmain (unsigned long magic, unsigned long addr); 45static void cls (void); 46static void itoa (char *buf, int base, int d); 47static void putchar (int c); 48void printf (const char *format, ...); 49 50/* @r{Check if MAGIC is valid and print the Multiboot information structure 51 pointed by ADDR.} */ 52void 53cmain (unsigned long magic, unsigned long addr) 54@{ 55 multiboot_info_t *mbi; 56 57 /* @r{Clear the screen.} */ 58 cls (); 59 60 /* @r{Am I booted by a Multiboot-compliant boot loader?} */ 61 if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 62 @{ 63 printf ("Invalid magic number: 0x%x\n", (unsigned) magic); 64 return; 65 @} 66 67 /* @r{Set MBI to the address of the Multiboot information structure.} */ 68 mbi = (multiboot_info_t *) addr; 69 70 /* @r{Print out the flags.} */ 71 printf ("flags = 0x%x\n", (unsigned) mbi->flags); 72 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); 77 78 /* @r{Is boot_device valid?} */ 79 if (CHECK_FLAG (mbi->flags, 1)) 80 printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device); 81 82 /* @r{Is the command line passed?} */ 83 if (CHECK_FLAG (mbi->flags, 2)) 84 printf ("cmdline = %s\n", (char *) mbi->cmdline); 85 86 /* @r{Are mods_* valid?} */ 87 if (CHECK_FLAG (mbi->flags, 3)) 88 @{ 89 module_t *mod; 90 int i; 91 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; 95 i < mbi->mods_count; 96 i++, mod++) 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); 101 @} 102 103 /* @r{Bits 4 and 5 are mutually exclusive!} */ 104 if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) 105 @{ 106 printf ("Both bits 4 and 5 are set.\n"); 107 return; 108 @} 109 110 /* @r{Is the symbol table of a.out valid?} */ 111 if (CHECK_FLAG (mbi->flags, 4)) 112 @{ 113 aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym); 114 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); 120 @} 121 122 /* @r{Is the section header table of ELF valid?} */ 123 if (CHECK_FLAG (mbi->flags, 5)) 124 @{ 125 elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec); 126 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); 131 @} 132 133 /* @r{Are mmap_* valid?} */ 134 if (CHECK_FLAG (mbi->flags, 6)) 135 @{ 136 memory_map_t *mmap; 137 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); 152 @} 153@} 154 155/* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */ 156static void 157cls (void) 158@{ 159 int i; 160 161 video = (unsigned char *) VIDEO; 162 163 for (i = 0; i < COLUMNS * LINES * 2; i++) 164 *(video + i) = 0; 165 166 xpos = 0; 167 ypos = 0; 168@} 169 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.} */ 173static void 174itoa (char *buf, int base, int d) 175@{ 176 char *p = buf; 177 char *p1, *p2; 178 unsigned long ud = d; 179 int divisor = 10; 180 181 /* @r{If %d is specified and D is minus, put `-' in the head.} */ 182 if (base == 'd' && d < 0) 183 @{ 184 *p++ = '-'; 185 buf++; 186 ud = -d; 187 @} 188 else if (base == 'x') 189 divisor = 16; 190 191 /* @r{Divide UD by DIVISOR until UD == 0.} */ 192 do 193 @{ 194 int remainder = ud % divisor; 195 196 *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; 197 @} 198 while (ud /= divisor); 199 200 /* @r{Terminate BUF.} */ 201 *p = 0; 202 203 /* @r{Reverse BUF.} */ 204 p1 = buf; 205 p2 = p - 1; 206 while (p1 < p2) 207 @{ 208 char tmp = *p1; 209 *p1 = *p2; 210 *p2 = tmp; 211 p1++; 212 p2--; 213 @} 214@} 215 216/* @r{Put the character C on the screen.} */ 217static void 218putchar (int c) 219@{ 220 if (c == '\n' || c == '\r') 221 @{ 222 newline: 223 xpos = 0; 224 ypos++; 225 if (ypos >= LINES) 226 ypos = 0; 227 return; 228 @} 229 230 *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; 231 *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; 232 233 xpos++; 234 if (xpos >= COLUMNS) 235 goto newline; 236@} 237 238/* @r{Format a string and print it on the screen, just like the libc 239 function printf.} */ 240void 241printf (const char *format, ...) 242@{ 243 char **arg = (char **) &format; 244 int c; 245 char buf[20]; 246 247 arg++; 248 249 while ((c = *format++) != 0) 250 @{ 251 if (c != '%') 252 putchar (c); 253 else 254 @{ 255 char *p; 256 257 c = *format++; 258 switch (c) 259 @{ 260 case 'd': 261 case 'u': 262 case 'x': 263 itoa (buf, c, *((int *) arg++)); 264 p = buf; 265 goto string; 266 break; 267 268 case 's': 269 p = *arg++; 270 if (! p) 271 p = "(null)"; 272 273 string: 274 while (*p) 275 putchar (*p++); 276 break; 277 278 default: 279 putchar (*((int *) arg++)); 280 break; 281 @} 282 @} 283 @} 284@} 285