17c478bd9Sstevel@tonic-gate/* @r{kernel.c - the C part of the kernel} */ 27c478bd9Sstevel@tonic-gate/* @r{Copyright (C) 1999 Free Software Foundation, Inc. 37c478bd9Sstevel@tonic-gate 47c478bd9Sstevel@tonic-gate This program is free software; you can redistribute it and/or modify 57c478bd9Sstevel@tonic-gate it under the terms of the GNU General Public License as published by 67c478bd9Sstevel@tonic-gate the Free Software Foundation; either version 2 of the License, or 77c478bd9Sstevel@tonic-gate (at your option) any later version. 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate This program is distributed in the hope that it will be useful, 107c478bd9Sstevel@tonic-gate but WITHOUT ANY WARRANTY; without even the implied warranty of 117c478bd9Sstevel@tonic-gate MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 127c478bd9Sstevel@tonic-gate GNU General Public License for more details. 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate You should have received a copy of the GNU General Public License 157c478bd9Sstevel@tonic-gate along with this program; if not, write to the Free Software 167c478bd9Sstevel@tonic-gate Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.} */ 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate#include <multiboot.h> 197c478bd9Sstevel@tonic-gate 207c478bd9Sstevel@tonic-gate/* @r{Macros.} */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate/* @r{Check if the bit BIT in FLAGS is set.} */ 237c478bd9Sstevel@tonic-gate#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate/* @r{Some screen stuff.} */ 267c478bd9Sstevel@tonic-gate/* @r{The number of columns.} */ 277c478bd9Sstevel@tonic-gate#define COLUMNS 80 287c478bd9Sstevel@tonic-gate/* @r{The number of lines.} */ 297c478bd9Sstevel@tonic-gate#define LINES 24 307c478bd9Sstevel@tonic-gate/* @r{The attribute of an character.} */ 317c478bd9Sstevel@tonic-gate#define ATTRIBUTE 7 327c478bd9Sstevel@tonic-gate/* @r{The video memory address.} */ 337c478bd9Sstevel@tonic-gate#define VIDEO 0xB8000 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate/* @r{Variables.} */ 367c478bd9Sstevel@tonic-gate/* @r{Save the X position.} */ 377c478bd9Sstevel@tonic-gatestatic int xpos; 387c478bd9Sstevel@tonic-gate/* @r{Save the Y position.} */ 397c478bd9Sstevel@tonic-gatestatic int ypos; 407c478bd9Sstevel@tonic-gate/* @r{Point to the video memory.} */ 417c478bd9Sstevel@tonic-gatestatic volatile unsigned char *video; 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate/* @r{Forward declarations.} */ 447c478bd9Sstevel@tonic-gatevoid cmain (unsigned long magic, unsigned long addr); 457c478bd9Sstevel@tonic-gatestatic void cls (void); 467c478bd9Sstevel@tonic-gatestatic void itoa (char *buf, int base, int d); 477c478bd9Sstevel@tonic-gatestatic void putchar (int c); 487c478bd9Sstevel@tonic-gatevoid printf (const char *format, ...); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate/* @r{Check if MAGIC is valid and print the Multiboot information structure 517c478bd9Sstevel@tonic-gate pointed by ADDR.} */ 527c478bd9Sstevel@tonic-gatevoid 537c478bd9Sstevel@tonic-gatecmain (unsigned long magic, unsigned long addr) 547c478bd9Sstevel@tonic-gate@{ 557c478bd9Sstevel@tonic-gate multiboot_info_t *mbi; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* @r{Clear the screen.} */ 587c478bd9Sstevel@tonic-gate cls (); 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* @r{Am I booted by a Multiboot-compliant boot loader?} */ 617c478bd9Sstevel@tonic-gate if (magic != MULTIBOOT_BOOTLOADER_MAGIC) 627c478bd9Sstevel@tonic-gate @{ 637c478bd9Sstevel@tonic-gate printf ("Invalid magic number: 0x%x\n", (unsigned) magic); 647c478bd9Sstevel@tonic-gate return; 657c478bd9Sstevel@tonic-gate @} 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* @r{Set MBI to the address of the Multiboot information structure.} */ 687c478bd9Sstevel@tonic-gate mbi = (multiboot_info_t *) addr; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* @r{Print out the flags.} */ 717c478bd9Sstevel@tonic-gate printf ("flags = 0x%x\n", (unsigned) mbi->flags); 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* @r{Are mem_* valid?} */ 747c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 0)) 757c478bd9Sstevel@tonic-gate printf ("mem_lower = %uKB, mem_upper = %uKB\n", 767c478bd9Sstevel@tonic-gate (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* @r{Is boot_device valid?} */ 797c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 1)) 807c478bd9Sstevel@tonic-gate printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device); 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* @r{Is the command line passed?} */ 837c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 2)) 847c478bd9Sstevel@tonic-gate printf ("cmdline = %s\n", (char *) mbi->cmdline); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate /* @r{Are mods_* valid?} */ 877c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 3)) 887c478bd9Sstevel@tonic-gate @{ 897c478bd9Sstevel@tonic-gate module_t *mod; 907c478bd9Sstevel@tonic-gate int i; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate printf ("mods_count = %d, mods_addr = 0x%x\n", 937c478bd9Sstevel@tonic-gate (int) mbi->mods_count, (int) mbi->mods_addr); 947c478bd9Sstevel@tonic-gate for (i = 0, mod = (module_t *) mbi->mods_addr; 957c478bd9Sstevel@tonic-gate i < mbi->mods_count; 967c478bd9Sstevel@tonic-gate i++, mod++) 977c478bd9Sstevel@tonic-gate printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n", 987c478bd9Sstevel@tonic-gate (unsigned) mod->mod_start, 997c478bd9Sstevel@tonic-gate (unsigned) mod->mod_end, 1007c478bd9Sstevel@tonic-gate (char *) mod->string); 1017c478bd9Sstevel@tonic-gate @} 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* @r{Bits 4 and 5 are mutually exclusive!} */ 1047c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) 1057c478bd9Sstevel@tonic-gate @{ 1067c478bd9Sstevel@tonic-gate printf ("Both bits 4 and 5 are set.\n"); 1077c478bd9Sstevel@tonic-gate return; 1087c478bd9Sstevel@tonic-gate @} 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* @r{Is the symbol table of a.out valid?} */ 1117c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 4)) 1127c478bd9Sstevel@tonic-gate @{ 1137c478bd9Sstevel@tonic-gate aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate printf ("aout_symbol_table: tabsize = 0x%0x, " 1167c478bd9Sstevel@tonic-gate "strsize = 0x%x, addr = 0x%x\n", 1177c478bd9Sstevel@tonic-gate (unsigned) aout_sym->tabsize, 1187c478bd9Sstevel@tonic-gate (unsigned) aout_sym->strsize, 1197c478bd9Sstevel@tonic-gate (unsigned) aout_sym->addr); 1207c478bd9Sstevel@tonic-gate @} 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate /* @r{Is the section header table of ELF valid?} */ 1237c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 5)) 1247c478bd9Sstevel@tonic-gate @{ 1257c478bd9Sstevel@tonic-gate elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec); 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate printf ("elf_sec: num = %u, size = 0x%x," 1287c478bd9Sstevel@tonic-gate " addr = 0x%x, shndx = 0x%x\n", 1297c478bd9Sstevel@tonic-gate (unsigned) elf_sec->num, (unsigned) elf_sec->size, 1307c478bd9Sstevel@tonic-gate (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx); 1317c478bd9Sstevel@tonic-gate @} 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* @r{Are mmap_* valid?} */ 1347c478bd9Sstevel@tonic-gate if (CHECK_FLAG (mbi->flags, 6)) 1357c478bd9Sstevel@tonic-gate @{ 1367c478bd9Sstevel@tonic-gate memory_map_t *mmap; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n", 1397c478bd9Sstevel@tonic-gate (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); 1407c478bd9Sstevel@tonic-gate for (mmap = (memory_map_t *) mbi->mmap_addr; 1417c478bd9Sstevel@tonic-gate (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; 1427c478bd9Sstevel@tonic-gate mmap = (memory_map_t *) ((unsigned long) mmap 1437c478bd9Sstevel@tonic-gate + mmap->size + sizeof (mmap->size))) 1447c478bd9Sstevel@tonic-gate printf (" size = 0x%x, base_addr = 0x%x%x," 1457c478bd9Sstevel@tonic-gate " length = 0x%x%x, type = 0x%x\n", 1467c478bd9Sstevel@tonic-gate (unsigned) mmap->size, 1477c478bd9Sstevel@tonic-gate (unsigned) mmap->base_addr_high, 1487c478bd9Sstevel@tonic-gate (unsigned) mmap->base_addr_low, 1497c478bd9Sstevel@tonic-gate (unsigned) mmap->length_high, 1507c478bd9Sstevel@tonic-gate (unsigned) mmap->length_low, 1517c478bd9Sstevel@tonic-gate (unsigned) mmap->type); 1527c478bd9Sstevel@tonic-gate @} 1537c478bd9Sstevel@tonic-gate@} 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate/* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */ 1567c478bd9Sstevel@tonic-gatestatic void 1577c478bd9Sstevel@tonic-gatecls (void) 1587c478bd9Sstevel@tonic-gate@{ 1597c478bd9Sstevel@tonic-gate int i; 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate video = (unsigned char *) VIDEO; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate for (i = 0; i < COLUMNS * LINES * 2; i++) 1647c478bd9Sstevel@tonic-gate *(video + i) = 0; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate xpos = 0; 1677c478bd9Sstevel@tonic-gate ypos = 0; 1687c478bd9Sstevel@tonic-gate@} 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate/* @r{Convert the integer D to a string and save the string in BUF. If 1717c478bd9Sstevel@tonic-gate BASE is equal to 'd', interpret that D is decimal, and if BASE is 1727c478bd9Sstevel@tonic-gate equal to 'x', interpret that D is hexadecimal.} */ 1737c478bd9Sstevel@tonic-gatestatic void 1747c478bd9Sstevel@tonic-gateitoa (char *buf, int base, int d) 1757c478bd9Sstevel@tonic-gate@{ 1767c478bd9Sstevel@tonic-gate char *p = buf; 1777c478bd9Sstevel@tonic-gate char *p1, *p2; 1787c478bd9Sstevel@tonic-gate unsigned long ud = d; 1797c478bd9Sstevel@tonic-gate int divisor = 10; 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* @r{If %d is specified and D is minus, put `-' in the head.} */ 1827c478bd9Sstevel@tonic-gate if (base == 'd' && d < 0) 1837c478bd9Sstevel@tonic-gate @{ 1847c478bd9Sstevel@tonic-gate *p++ = '-'; 1857c478bd9Sstevel@tonic-gate buf++; 1867c478bd9Sstevel@tonic-gate ud = -d; 1877c478bd9Sstevel@tonic-gate @} 1887c478bd9Sstevel@tonic-gate else if (base == 'x') 1897c478bd9Sstevel@tonic-gate divisor = 16; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* @r{Divide UD by DIVISOR until UD == 0.} */ 1927c478bd9Sstevel@tonic-gate do 1937c478bd9Sstevel@tonic-gate @{ 1947c478bd9Sstevel@tonic-gate int remainder = ud % divisor; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; 1977c478bd9Sstevel@tonic-gate @} 1987c478bd9Sstevel@tonic-gate while (ud /= divisor); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* @r{Terminate BUF.} */ 2017c478bd9Sstevel@tonic-gate *p = 0; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /* @r{Reverse BUF.} */ 2047c478bd9Sstevel@tonic-gate p1 = buf; 2057c478bd9Sstevel@tonic-gate p2 = p - 1; 2067c478bd9Sstevel@tonic-gate while (p1 < p2) 2077c478bd9Sstevel@tonic-gate @{ 2087c478bd9Sstevel@tonic-gate char tmp = *p1; 2097c478bd9Sstevel@tonic-gate *p1 = *p2; 2107c478bd9Sstevel@tonic-gate *p2 = tmp; 2117c478bd9Sstevel@tonic-gate p1++; 2127c478bd9Sstevel@tonic-gate p2--; 2137c478bd9Sstevel@tonic-gate @} 2147c478bd9Sstevel@tonic-gate@} 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate/* @r{Put the character C on the screen.} */ 2177c478bd9Sstevel@tonic-gatestatic void 2187c478bd9Sstevel@tonic-gateputchar (int c) 2197c478bd9Sstevel@tonic-gate@{ 2207c478bd9Sstevel@tonic-gate if (c == '\n' || c == '\r') 2217c478bd9Sstevel@tonic-gate @{ 2227c478bd9Sstevel@tonic-gate newline: 2237c478bd9Sstevel@tonic-gate xpos = 0; 2247c478bd9Sstevel@tonic-gate ypos++; 2257c478bd9Sstevel@tonic-gate if (ypos >= LINES) 2267c478bd9Sstevel@tonic-gate ypos = 0; 2277c478bd9Sstevel@tonic-gate return; 2287c478bd9Sstevel@tonic-gate @} 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; 2317c478bd9Sstevel@tonic-gate *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate xpos++; 2347c478bd9Sstevel@tonic-gate if (xpos >= COLUMNS) 2357c478bd9Sstevel@tonic-gate goto newline; 2367c478bd9Sstevel@tonic-gate@} 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate/* @r{Format a string and print it on the screen, just like the libc 2397c478bd9Sstevel@tonic-gate function printf.} */ 2407c478bd9Sstevel@tonic-gatevoid 2417c478bd9Sstevel@tonic-gateprintf (const char *format, ...) 2427c478bd9Sstevel@tonic-gate@{ 2437c478bd9Sstevel@tonic-gate char **arg = (char **) &format; 2447c478bd9Sstevel@tonic-gate int c; 2457c478bd9Sstevel@tonic-gate char buf[20]; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate arg++; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate while ((c = *format++) != 0) 2507c478bd9Sstevel@tonic-gate @{ 2517c478bd9Sstevel@tonic-gate if (c != '%') 2527c478bd9Sstevel@tonic-gate putchar (c); 2537c478bd9Sstevel@tonic-gate else 2547c478bd9Sstevel@tonic-gate @{ 2557c478bd9Sstevel@tonic-gate char *p; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate c = *format++; 2587c478bd9Sstevel@tonic-gate switch (c) 2597c478bd9Sstevel@tonic-gate @{ 2607c478bd9Sstevel@tonic-gate case 'd': 2617c478bd9Sstevel@tonic-gate case 'u': 2627c478bd9Sstevel@tonic-gate case 'x': 2637c478bd9Sstevel@tonic-gate itoa (buf, c, *((int *) arg++)); 2647c478bd9Sstevel@tonic-gate p = buf; 2657c478bd9Sstevel@tonic-gate goto string; 2667c478bd9Sstevel@tonic-gate break; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate case 's': 2697c478bd9Sstevel@tonic-gate p = *arg++; 2707c478bd9Sstevel@tonic-gate if (! p) 2717c478bd9Sstevel@tonic-gate p = "(null)"; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate string: 2747c478bd9Sstevel@tonic-gate while (*p) 2757c478bd9Sstevel@tonic-gate putchar (*p++); 2767c478bd9Sstevel@tonic-gate break; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate default: 2797c478bd9Sstevel@tonic-gate putchar (*((int *) arg++)); 2807c478bd9Sstevel@tonic-gate break; 2817c478bd9Sstevel@tonic-gate @} 2827c478bd9Sstevel@tonic-gate @} 2837c478bd9Sstevel@tonic-gate @} 2847c478bd9Sstevel@tonic-gate@} 285