xref: /onnv-gate/usr/src/grub/grub-0.97/docs/kernel.c.texi (revision 8044:b3af80bbf173)
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