1 /* kernel.c - the C part of the kernel */
2 /* Copyright (C) 1999 Free Software Foundation, Inc.
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.
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.
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>
22 /* Check if the bit BIT in FLAGS is set. */
23 #define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
25 /* Some screen stuff. */
26 /* The number of columns. */
28 /* The number of lines. */
30 /* The attribute of an character. */
32 /* The video memory address. */
36 /* Save the X position. */
38 /* Save the Y position. */
40 /* Point to the video memory. */
41 static volatile unsigned char *video
;
43 /* 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 /* Check if MAGIC is valid and print the Multiboot information structure
53 cmain (unsigned long magic
, unsigned long addr
)
55 multiboot_info_t
*mbi
;
57 /* Clear the screen. */
60 /* Am I booted by a Multiboot-compliant boot loader? */
61 if (magic
!= MULTIBOOT_BOOTLOADER_MAGIC
)
63 printf ("Invalid magic number: 0x%x\n", (unsigned) magic
);
67 /* Set MBI to the address of the Multiboot information structure. */
68 mbi
= (multiboot_info_t
*) addr
;
70 /* Print out the flags. */
71 printf ("flags = 0x%x\n", (unsigned) mbi
->flags
);
73 /* 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 /* Is boot_device valid? */
79 if (CHECK_FLAG (mbi
->flags
, 1))
80 printf ("boot_device = 0x%x\n", (unsigned) mbi
->boot_device
);
82 /* Is the command line passed? */
83 if (CHECK_FLAG (mbi
->flags
, 2))
84 printf ("cmdline = %s\n", (char *) mbi
->cmdline
);
86 /* Are mods_* valid? */
87 if (CHECK_FLAG (mbi
->flags
, 3))
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
;
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
);
103 /* Bits 4 and 5 are mutually exclusive! */
104 if (CHECK_FLAG (mbi
->flags
, 4) && CHECK_FLAG (mbi
->flags
, 5))
106 printf ("Both bits 4 and 5 are set.\n");
110 /* Is the symbol table of a.out valid? */
111 if (CHECK_FLAG (mbi
->flags
, 4))
113 aout_symbol_table_t
*aout_sym
= &(mbi
->u
.aout_sym
);
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
);
122 /* Is the section header table of ELF valid? */
123 if (CHECK_FLAG (mbi
->flags
, 5))
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
);
133 /* Are mmap_* valid? */
134 if (CHECK_FLAG (mbi
->flags
, 6))
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
);
155 /* Clear the screen and initialize VIDEO, XPOS and YPOS. */
161 video
= (unsigned char *) VIDEO
;
163 for (i
= 0; i
< COLUMNS
* LINES
* 2; i
++)
170 /* 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. */
174 itoa (char *buf
, int base
, int d
)
178 unsigned long ud
= d
;
181 /* If %d is specified and D is minus, put `-' in the head. */
182 if (base
== 'd' && d
< 0)
188 else if (base
== 'x')
191 /* Divide UD by DIVISOR until UD == 0. */
194 int remainder
= ud
% divisor
;
196 *p
++ = (remainder
< 10) ? remainder
+ '0' : remainder
+ 'a' - 10;
198 while (ud
/= divisor
);
216 /* Put the character C on the screen. */
220 if (c
== '\n' || c
== '\r')
230 *(video
+ (xpos
+ ypos
* COLUMNS
) * 2) = c
& 0xFF;
231 *(video
+ (xpos
+ ypos
* COLUMNS
) * 2 + 1) = ATTRIBUTE
;
238 /* Format a string and print it on the screen, just like the libc
241 printf (const char *format
, ...)
243 char **arg
= (char **) &format
;
249 while ((c
= *format
++) != 0)
263 itoa (buf
, c
, *((int *) arg
++));
279 putchar (*((int *) arg
++));