Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / common / boot / grub / docs / kernel.c.texi
blobbd61bd58e01b9be7fd68e27c9815bf96c65f4b94
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.} */
18 #include <multiboot.h>
20 /* @r{Macros.} */
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.} */
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
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;
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
51    pointed by ADDR.} */
52 void
53 cmain (unsigned long magic, unsigned long addr)
55   multiboot_info_t *mbi;
56   
57   /* @r{Clear the screen.} */
58   cls ();
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     @}
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);
81   
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))
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     @}
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     @}
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     @}
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);
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     @}
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 @}    
155 /* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */
156 static void
157 cls (void)
159   int i;
161   video = (unsigned char *) VIDEO;
162   
163   for (i = 0; i < COLUMNS * LINES * 2; i++)
164     *(video + i) = 0;
166   xpos = 0;
167   ypos = 0;
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)
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;
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);
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     @}
216 /* @r{Put the character C on the screen.} */
217 static void
218 putchar (int c)
220   if (c == '\n' || c == '\r')
221     @{
222     newline:
223       xpos = 0;
224       ypos++;
225       if (ypos >= LINES)
226         ypos = 0;
227       return;
228     @}
230   *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
231   *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
233   xpos++;
234   if (xpos >= COLUMNS)
235     goto newline;
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, ...)
243   char **arg = (char **) &format;
244   int c;
245   char buf[20];
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;
268             case 's':
269               p = *arg++;
270               if (! p)
271                 p = "(null)";
273             string:
274               while (*p)
275                 putchar (*p++);
276               break;
278             default:
279               putchar (*((int *) arg++));
280               break;
281             @}
282         @}
283     @}