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