xref: /titanic_52/usr/src/grub/grub-0.97/docs/kernel.c.texi (revision 1b8adde7ba7d5e04395c141c5400dc2cffd7d809)
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