Home | History | Annotate | Download | only in docs
      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.} */
     37 static int xpos;
     38 /* @r{Save the Y position.} */
     39 static int ypos;
     40 /* @r{Point to the video memory.} */
     41 static volatile unsigned char *video;
     42 
     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, ...);
     49 
     50 /* @r{Check if MAGIC is valid and print the Multiboot information structure
     51    pointed by ADDR.} */
     52 void
     53 cmain (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.} */
    156 static void
    157 cls (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.} */
    173 static void
    174 itoa (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.} */
    217 static void
    218 putchar (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.} */
    240 void
    241 printf (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