1*8044SWilliam.Kucharski@Sun.COM/* @r{kernel.c - the C part of the kernel} */ 2*8044SWilliam.Kucharski@Sun.COM/* @r{Copyright (C) 1999 Free Software Foundation, Inc. 3*8044SWilliam.Kucharski@Sun.COM 4*8044SWilliam.Kucharski@Sun.COM This program is free software; you can redistribute it and/or modify 5*8044SWilliam.Kucharski@Sun.COM it under the terms of the GNU General Public License as published by 6*8044SWilliam.Kucharski@Sun.COM the Free Software Foundation; either version 2 of the License, or 7*8044SWilliam.Kucharski@Sun.COM (at your option) any later version. 8*8044SWilliam.Kucharski@Sun.COM 9*8044SWilliam.Kucharski@Sun.COM This program is distributed in the hope that it will be useful, 10*8044SWilliam.Kucharski@Sun.COM but WITHOUT ANY WARRANTY; without even the implied warranty of 11*8044SWilliam.Kucharski@Sun.COM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*8044SWilliam.Kucharski@Sun.COM GNU General Public License for more details. 13*8044SWilliam.Kucharski@Sun.COM 14*8044SWilliam.Kucharski@Sun.COM You should have received a copy of the GNU General Public License 15*8044SWilliam.Kucharski@Sun.COM along with this program; if not, write to the Free Software 16*8044SWilliam.Kucharski@Sun.COM Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */ 17*8044SWilliam.Kucharski@Sun.COM 18*8044SWilliam.Kucharski@Sun.COM#include <multiboot.h> 19*8044SWilliam.Kucharski@Sun.COM 20*8044SWilliam.Kucharski@Sun.COM/* @r{Macros.} */ 21*8044SWilliam.Kucharski@Sun.COM 22*8044SWilliam.Kucharski@Sun.COM/* @r{Check if the bit BIT in FLAGS is set.} */ 23*8044SWilliam.Kucharski@Sun.COM#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) 24*8044SWilliam.Kucharski@Sun.COM 25*8044SWilliam.Kucharski@Sun.COM/* @r{Some screen stuff.} */ 26*8044SWilliam.Kucharski@Sun.COM/* @r{The number of columns.} */ 27*8044SWilliam.Kucharski@Sun.COM#define COLUMNS 80 28*8044SWilliam.Kucharski@Sun.COM/* @r{The number of lines.} */ 29*8044SWilliam.Kucharski@Sun.COM#define LINES 24 30*8044SWilliam.Kucharski@Sun.COM/* @r{The attribute of an character.} */ 31*8044SWilliam.Kucharski@Sun.COM#define ATTRIBUTE 7 32*8044SWilliam.Kucharski@Sun.COM/* @r{The video memory address.} */ 33*8044SWilliam.Kucharski@Sun.COM#define VIDEO 0xB8000 34*8044SWilliam.Kucharski@Sun.COM 35*8044SWilliam.Kucharski@Sun.COM/* @r{Variables.} */ 36*8044SWilliam.Kucharski@Sun.COM/* @r{Save the X position.} */ 37*8044SWilliam.Kucharski@Sun.COMstatic int xpos; 38*8044SWilliam.Kucharski@Sun.COM/* @r{Save the Y position.} */ 39*8044SWilliam.Kucharski@Sun.COMstatic int ypos; 40*8044SWilliam.Kucharski@Sun.COM/* @r{Point to the video memory.} */ 41*8044SWilliam.Kucharski@Sun.COMstatic volatile unsigned char *video; 42*8044SWilliam.Kucharski@Sun.COM 43*8044SWilliam.Kucharski@Sun.COM/* @r{Forward declarations.} */ 44*8044SWilliam.Kucharski@Sun.COMvoid cmain (unsigned long magic, unsigned long addr); 45*8044SWilliam.Kucharski@Sun.COMstatic void cls (void); 46*8044SWilliam.Kucharski@Sun.COMstatic void itoa (char *buf, int base, int d); 47*8044SWilliam.Kucharski@Sun.COMstatic void putchar (int c); 48*8044SWilliam.Kucharski@Sun.COMvoid printf (const char *format, ...); 49*8044SWilliam.Kucharski@Sun.COM 50*8044SWilliam.Kucharski@Sun.COM/* @r{Check if MAGIC is valid and print the Multiboot information structure 51*8044SWilliam.Kucharski@Sun.COM pointed by ADDR.} */ 52*8044SWilliam.Kucharski@Sun.COMvoid 53*8044SWilliam.Kucharski@Sun.COMcmain (unsigned long magic, unsigned long addr) 54*8044SWilliam.Kucharski@Sun.COM@{ 55*8044SWilliam.Kucharski@Sun.COM multiboot_info_t *mbi; 56*8044SWilliam.Kucharski@Sun.COM 57*8044SWilliam.Kucharski@Sun.COM /* @r{Clear the screen.} */ 58*8044SWilliam.Kucharski@Sun.COM cls (); 59*8044SWilliam.Kucharski@Sun.COM 60*8044SWilliam.Kucharski@Sun.COM /* @r{Am I booted by a Multiboot-compliant boot loader?} */ 61*8044SWilliam.Kucharski@Sun.COM if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 62*8044SWilliam.Kucharski@Sun.COM @{ 63*8044SWilliam.Kucharski@Sun.COM printf ("Invalid magic number: 0x%x\n", (unsigned) magic); 64*8044SWilliam.Kucharski@Sun.COM return; 65*8044SWilliam.Kucharski@Sun.COM @} 66*8044SWilliam.Kucharski@Sun.COM 67*8044SWilliam.Kucharski@Sun.COM /* @r{Set MBI to the address of the Multiboot information structure.} */ 68*8044SWilliam.Kucharski@Sun.COM mbi = (multiboot_info_t *) addr; 69*8044SWilliam.Kucharski@Sun.COM 70*8044SWilliam.Kucharski@Sun.COM /* @r{Print out the flags.} */ 71*8044SWilliam.Kucharski@Sun.COM printf ("flags = 0x%x\n", (unsigned) mbi->flags); 72*8044SWilliam.Kucharski@Sun.COM 73*8044SWilliam.Kucharski@Sun.COM /* @r{Are mem_* valid?} */ 74*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 0)) 75*8044SWilliam.Kucharski@Sun.COM printf ("mem_lower = %uKB, mem_upper = %uKB\n", 76*8044SWilliam.Kucharski@Sun.COM (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); 77*8044SWilliam.Kucharski@Sun.COM 78*8044SWilliam.Kucharski@Sun.COM /* @r{Is boot_device valid?} */ 79*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 1)) 80*8044SWilliam.Kucharski@Sun.COM printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device); 81*8044SWilliam.Kucharski@Sun.COM 82*8044SWilliam.Kucharski@Sun.COM /* @r{Is the command line passed?} */ 83*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 2)) 84*8044SWilliam.Kucharski@Sun.COM printf ("cmdline = %s\n", (char *) mbi->cmdline); 85*8044SWilliam.Kucharski@Sun.COM 86*8044SWilliam.Kucharski@Sun.COM /* @r{Are mods_* valid?} */ 87*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 3)) 88*8044SWilliam.Kucharski@Sun.COM @{ 89*8044SWilliam.Kucharski@Sun.COM module_t *mod; 90*8044SWilliam.Kucharski@Sun.COM int i; 91*8044SWilliam.Kucharski@Sun.COM 92*8044SWilliam.Kucharski@Sun.COM printf ("mods_count = %d, mods_addr = 0x%x\n", 93*8044SWilliam.Kucharski@Sun.COM (int) mbi->mods_count, (int) mbi->mods_addr); 94*8044SWilliam.Kucharski@Sun.COM for (i = 0, mod = (module_t *) mbi->mods_addr; 95*8044SWilliam.Kucharski@Sun.COM i < mbi->mods_count; 96*8044SWilliam.Kucharski@Sun.COM i++, mod++) 97*8044SWilliam.Kucharski@Sun.COM printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n", 98*8044SWilliam.Kucharski@Sun.COM (unsigned) mod->mod_start, 99*8044SWilliam.Kucharski@Sun.COM (unsigned) mod->mod_end, 100*8044SWilliam.Kucharski@Sun.COM (char *) mod->string); 101*8044SWilliam.Kucharski@Sun.COM @} 102*8044SWilliam.Kucharski@Sun.COM 103*8044SWilliam.Kucharski@Sun.COM /* @r{Bits 4 and 5 are mutually exclusive!} */ 104*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) 105*8044SWilliam.Kucharski@Sun.COM @{ 106*8044SWilliam.Kucharski@Sun.COM printf ("Both bits 4 and 5 are set.\n"); 107*8044SWilliam.Kucharski@Sun.COM return; 108*8044SWilliam.Kucharski@Sun.COM @} 109*8044SWilliam.Kucharski@Sun.COM 110*8044SWilliam.Kucharski@Sun.COM /* @r{Is the symbol table of a.out valid?} */ 111*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 4)) 112*8044SWilliam.Kucharski@Sun.COM @{ 113*8044SWilliam.Kucharski@Sun.COM aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym); 114*8044SWilliam.Kucharski@Sun.COM 115*8044SWilliam.Kucharski@Sun.COM printf ("aout_symbol_table: tabsize = 0x%0x, " 116*8044SWilliam.Kucharski@Sun.COM "strsize = 0x%x, addr = 0x%x\n", 117*8044SWilliam.Kucharski@Sun.COM (unsigned) aout_sym->tabsize, 118*8044SWilliam.Kucharski@Sun.COM (unsigned) aout_sym->strsize, 119*8044SWilliam.Kucharski@Sun.COM (unsigned) aout_sym->addr); 120*8044SWilliam.Kucharski@Sun.COM @} 121*8044SWilliam.Kucharski@Sun.COM 122*8044SWilliam.Kucharski@Sun.COM /* @r{Is the section header table of ELF valid?} */ 123*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 5)) 124*8044SWilliam.Kucharski@Sun.COM @{ 125*8044SWilliam.Kucharski@Sun.COM elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec); 126*8044SWilliam.Kucharski@Sun.COM 127*8044SWilliam.Kucharski@Sun.COM printf ("elf_sec: num = %u, size = 0x%x," 128*8044SWilliam.Kucharski@Sun.COM " addr = 0x%x, shndx = 0x%x\n", 129*8044SWilliam.Kucharski@Sun.COM (unsigned) elf_sec->num, (unsigned) elf_sec->size, 130*8044SWilliam.Kucharski@Sun.COM (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); 131*8044SWilliam.Kucharski@Sun.COM @} 132*8044SWilliam.Kucharski@Sun.COM 133*8044SWilliam.Kucharski@Sun.COM /* @r{Are mmap_* valid?} */ 134*8044SWilliam.Kucharski@Sun.COM if (CHECK_FLAG (mbi->flags, 6)) 135*8044SWilliam.Kucharski@Sun.COM @{ 136*8044SWilliam.Kucharski@Sun.COM memory_map_t *mmap; 137*8044SWilliam.Kucharski@Sun.COM 138*8044SWilliam.Kucharski@Sun.COM printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n", 139*8044SWilliam.Kucharski@Sun.COM (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); 140*8044SWilliam.Kucharski@Sun.COM for (mmap = (memory_map_t *) mbi->mmap_addr; 141*8044SWilliam.Kucharski@Sun.COM (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; 142*8044SWilliam.Kucharski@Sun.COM mmap = (memory_map_t *) ((unsigned long) mmap 143*8044SWilliam.Kucharski@Sun.COM + mmap->size + sizeof (mmap->size))) 144*8044SWilliam.Kucharski@Sun.COM printf (" size = 0x%x, base_addr = 0x%x%x," 145*8044SWilliam.Kucharski@Sun.COM " length = 0x%x%x, type = 0x%x\n", 146*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->size, 147*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->base_addr_high, 148*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->base_addr_low, 149*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->length_high, 150*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->length_low, 151*8044SWilliam.Kucharski@Sun.COM (unsigned) mmap->type); 152*8044SWilliam.Kucharski@Sun.COM @} 153*8044SWilliam.Kucharski@Sun.COM@} 154*8044SWilliam.Kucharski@Sun.COM 155*8044SWilliam.Kucharski@Sun.COM/* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */ 156*8044SWilliam.Kucharski@Sun.COMstatic void 157*8044SWilliam.Kucharski@Sun.COMcls (void) 158*8044SWilliam.Kucharski@Sun.COM@{ 159*8044SWilliam.Kucharski@Sun.COM int i; 160*8044SWilliam.Kucharski@Sun.COM 161*8044SWilliam.Kucharski@Sun.COM video = (unsigned char *) VIDEO; 162*8044SWilliam.Kucharski@Sun.COM 163*8044SWilliam.Kucharski@Sun.COM for (i = 0; i < COLUMNS * LINES * 2; i++) 164*8044SWilliam.Kucharski@Sun.COM *(video + i) = 0; 165*8044SWilliam.Kucharski@Sun.COM 166*8044SWilliam.Kucharski@Sun.COM xpos = 0; 167*8044SWilliam.Kucharski@Sun.COM ypos = 0; 168*8044SWilliam.Kucharski@Sun.COM@} 169*8044SWilliam.Kucharski@Sun.COM 170*8044SWilliam.Kucharski@Sun.COM/* @r{Convert the integer D to a string and save the string in BUF. If 171*8044SWilliam.Kucharski@Sun.COM BASE is equal to 'd', interpret that D is decimal, and if BASE is 172*8044SWilliam.Kucharski@Sun.COM equal to 'x', interpret that D is hexadecimal.} */ 173*8044SWilliam.Kucharski@Sun.COMstatic void 174*8044SWilliam.Kucharski@Sun.COMitoa (char *buf, int base, int d) 175*8044SWilliam.Kucharski@Sun.COM@{ 176*8044SWilliam.Kucharski@Sun.COM char *p = buf; 177*8044SWilliam.Kucharski@Sun.COM char *p1, *p2; 178*8044SWilliam.Kucharski@Sun.COM unsigned long ud = d; 179*8044SWilliam.Kucharski@Sun.COM int divisor = 10; 180*8044SWilliam.Kucharski@Sun.COM 181*8044SWilliam.Kucharski@Sun.COM /* @r{If %d is specified and D is minus, put `-' in the head.} */ 182*8044SWilliam.Kucharski@Sun.COM if (base == 'd' && d < 0) 183*8044SWilliam.Kucharski@Sun.COM @{ 184*8044SWilliam.Kucharski@Sun.COM *p++ = '-'; 185*8044SWilliam.Kucharski@Sun.COM buf++; 186*8044SWilliam.Kucharski@Sun.COM ud = -d; 187*8044SWilliam.Kucharski@Sun.COM @} 188*8044SWilliam.Kucharski@Sun.COM else if (base == 'x') 189*8044SWilliam.Kucharski@Sun.COM divisor = 16; 190*8044SWilliam.Kucharski@Sun.COM 191*8044SWilliam.Kucharski@Sun.COM /* @r{Divide UD by DIVISOR until UD == 0.} */ 192*8044SWilliam.Kucharski@Sun.COM do 193*8044SWilliam.Kucharski@Sun.COM @{ 194*8044SWilliam.Kucharski@Sun.COM int remainder = ud % divisor; 195*8044SWilliam.Kucharski@Sun.COM 196*8044SWilliam.Kucharski@Sun.COM *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; 197*8044SWilliam.Kucharski@Sun.COM @} 198*8044SWilliam.Kucharski@Sun.COM while (ud /= divisor); 199*8044SWilliam.Kucharski@Sun.COM 200*8044SWilliam.Kucharski@Sun.COM /* @r{Terminate BUF.} */ 201*8044SWilliam.Kucharski@Sun.COM *p = 0; 202*8044SWilliam.Kucharski@Sun.COM 203*8044SWilliam.Kucharski@Sun.COM /* @r{Reverse BUF.} */ 204*8044SWilliam.Kucharski@Sun.COM p1 = buf; 205*8044SWilliam.Kucharski@Sun.COM p2 = p - 1; 206*8044SWilliam.Kucharski@Sun.COM while (p1 < p2) 207*8044SWilliam.Kucharski@Sun.COM @{ 208*8044SWilliam.Kucharski@Sun.COM char tmp = *p1; 209*8044SWilliam.Kucharski@Sun.COM *p1 = *p2; 210*8044SWilliam.Kucharski@Sun.COM *p2 = tmp; 211*8044SWilliam.Kucharski@Sun.COM p1++; 212*8044SWilliam.Kucharski@Sun.COM p2--; 213*8044SWilliam.Kucharski@Sun.COM @} 214*8044SWilliam.Kucharski@Sun.COM@} 215*8044SWilliam.Kucharski@Sun.COM 216*8044SWilliam.Kucharski@Sun.COM/* @r{Put the character C on the screen.} */ 217*8044SWilliam.Kucharski@Sun.COMstatic void 218*8044SWilliam.Kucharski@Sun.COMputchar (int c) 219*8044SWilliam.Kucharski@Sun.COM@{ 220*8044SWilliam.Kucharski@Sun.COM if (c == '\n' || c == '\r') 221*8044SWilliam.Kucharski@Sun.COM @{ 222*8044SWilliam.Kucharski@Sun.COM newline: 223*8044SWilliam.Kucharski@Sun.COM xpos = 0; 224*8044SWilliam.Kucharski@Sun.COM ypos++; 225*8044SWilliam.Kucharski@Sun.COM if (ypos >= LINES) 226*8044SWilliam.Kucharski@Sun.COM ypos = 0; 227*8044SWilliam.Kucharski@Sun.COM return; 228*8044SWilliam.Kucharski@Sun.COM @} 229*8044SWilliam.Kucharski@Sun.COM 230*8044SWilliam.Kucharski@Sun.COM *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; 231*8044SWilliam.Kucharski@Sun.COM *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; 232*8044SWilliam.Kucharski@Sun.COM 233*8044SWilliam.Kucharski@Sun.COM xpos++; 234*8044SWilliam.Kucharski@Sun.COM if (xpos >= COLUMNS) 235*8044SWilliam.Kucharski@Sun.COM goto newline; 236*8044SWilliam.Kucharski@Sun.COM@} 237*8044SWilliam.Kucharski@Sun.COM 238*8044SWilliam.Kucharski@Sun.COM/* @r{Format a string and print it on the screen, just like the libc 239*8044SWilliam.Kucharski@Sun.COM function printf.} */ 240*8044SWilliam.Kucharski@Sun.COMvoid 241*8044SWilliam.Kucharski@Sun.COMprintf (const char *format, ...) 242*8044SWilliam.Kucharski@Sun.COM@{ 243*8044SWilliam.Kucharski@Sun.COM char **arg = (char **) &format; 244*8044SWilliam.Kucharski@Sun.COM int c; 245*8044SWilliam.Kucharski@Sun.COM char buf[20]; 246*8044SWilliam.Kucharski@Sun.COM 247*8044SWilliam.Kucharski@Sun.COM arg++; 248*8044SWilliam.Kucharski@Sun.COM 249*8044SWilliam.Kucharski@Sun.COM while ((c = *format++) != 0) 250*8044SWilliam.Kucharski@Sun.COM @{ 251*8044SWilliam.Kucharski@Sun.COM if (c != '%') 252*8044SWilliam.Kucharski@Sun.COM putchar (c); 253*8044SWilliam.Kucharski@Sun.COM else 254*8044SWilliam.Kucharski@Sun.COM @{ 255*8044SWilliam.Kucharski@Sun.COM char *p; 256*8044SWilliam.Kucharski@Sun.COM 257*8044SWilliam.Kucharski@Sun.COM c = *format++; 258*8044SWilliam.Kucharski@Sun.COM switch (c) 259*8044SWilliam.Kucharski@Sun.COM @{ 260*8044SWilliam.Kucharski@Sun.COM case 'd': 261*8044SWilliam.Kucharski@Sun.COM case 'u': 262*8044SWilliam.Kucharski@Sun.COM case 'x': 263*8044SWilliam.Kucharski@Sun.COM itoa (buf, c, *((int *) arg++)); 264*8044SWilliam.Kucharski@Sun.COM p = buf; 265*8044SWilliam.Kucharski@Sun.COM goto string; 266*8044SWilliam.Kucharski@Sun.COM break; 267*8044SWilliam.Kucharski@Sun.COM 268*8044SWilliam.Kucharski@Sun.COM case 's': 269*8044SWilliam.Kucharski@Sun.COM p = *arg++; 270*8044SWilliam.Kucharski@Sun.COM if (! p) 271*8044SWilliam.Kucharski@Sun.COM p = "(null)"; 272*8044SWilliam.Kucharski@Sun.COM 273*8044SWilliam.Kucharski@Sun.COM string: 274*8044SWilliam.Kucharski@Sun.COM while (*p) 275*8044SWilliam.Kucharski@Sun.COM putchar (*p++); 276*8044SWilliam.Kucharski@Sun.COM break; 277*8044SWilliam.Kucharski@Sun.COM 278*8044SWilliam.Kucharski@Sun.COM default: 279*8044SWilliam.Kucharski@Sun.COM putchar (*((int *) arg++)); 280*8044SWilliam.Kucharski@Sun.COM break; 281*8044SWilliam.Kucharski@Sun.COM @} 282*8044SWilliam.Kucharski@Sun.COM @} 283*8044SWilliam.Kucharski@Sun.COM @} 284*8044SWilliam.Kucharski@Sun.COM@} 285