~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/boot/main.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /* -*- linux-c -*- ------------------------------------------------------- *
  3  *
  4  *   Copyright (C) 1991, 1992 Linus Torvalds
  5  *   Copyright 2007 rPath, Inc. - All Rights Reserved
  6  *   Copyright 2009 Intel Corporation; author H. Peter Anvin
  7  *
  8  * ----------------------------------------------------------------------- */
  9 
 10 /*
 11  * Main module for the real-mode kernel code
 12  */
 13 #include <linux/build_bug.h>
 14 
 15 #include "boot.h"
 16 #include "string.h"
 17 
 18 struct boot_params boot_params __attribute__((aligned(16)));
 19 
 20 struct port_io_ops pio_ops;
 21 
 22 char *HEAP = _end;
 23 char *heap_end = _end;          /* Default end of heap = no heap */
 24 
 25 /*
 26  * Copy the header into the boot parameter block.  Since this
 27  * screws up the old-style command line protocol, adjust by
 28  * filling in the new-style command line pointer instead.
 29  */
 30 static void copy_boot_params(void)
 31 {
 32         struct old_cmdline {
 33                 u16 cl_magic;
 34                 u16 cl_offset;
 35         };
 36         const struct old_cmdline * const oldcmd = absolute_pointer(OLD_CL_ADDRESS);
 37 
 38         BUILD_BUG_ON(sizeof(boot_params) != 4096);
 39         memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
 40 
 41         if (!boot_params.hdr.cmd_line_ptr && oldcmd->cl_magic == OLD_CL_MAGIC) {
 42                 /* Old-style command line protocol */
 43                 u16 cmdline_seg;
 44 
 45                 /*
 46                  * Figure out if the command line falls in the region
 47                  * of memory that an old kernel would have copied up
 48                  * to 0x90000...
 49                  */
 50                 if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
 51                         cmdline_seg = ds();
 52                 else
 53                         cmdline_seg = 0x9000;
 54 
 55                 boot_params.hdr.cmd_line_ptr = (cmdline_seg << 4) + oldcmd->cl_offset;
 56         }
 57 }
 58 
 59 /*
 60  * Query the keyboard lock status as given by the BIOS, and
 61  * set the keyboard repeat rate to maximum.  Unclear why the latter
 62  * is done here; this might be possible to kill off as stale code.
 63  */
 64 static void keyboard_init(void)
 65 {
 66         struct biosregs ireg, oreg;
 67 
 68         initregs(&ireg);
 69 
 70         ireg.ah = 0x02;         /* Get keyboard status */
 71         intcall(0x16, &ireg, &oreg);
 72         boot_params.kbd_status = oreg.al;
 73 
 74         ireg.ax = 0x0305;       /* Set keyboard repeat rate */
 75         intcall(0x16, &ireg, NULL);
 76 }
 77 
 78 /*
 79  * Get Intel SpeedStep (IST) information.
 80  */
 81 static void query_ist(void)
 82 {
 83         struct biosregs ireg, oreg;
 84 
 85         /*
 86          * Some older BIOSes apparently crash on this call, so filter
 87          * it from machines too old to have SpeedStep at all.
 88          */
 89         if (cpu.level < 6)
 90                 return;
 91 
 92         initregs(&ireg);
 93         ireg.ax  = 0xe980;       /* IST Support */
 94         ireg.edx = 0x47534943;   /* Request value */
 95         intcall(0x15, &ireg, &oreg);
 96 
 97         boot_params.ist_info.signature  = oreg.eax;
 98         boot_params.ist_info.command    = oreg.ebx;
 99         boot_params.ist_info.event      = oreg.ecx;
100         boot_params.ist_info.perf_level = oreg.edx;
101 }
102 
103 /*
104  * Tell the BIOS what CPU mode we intend to run in.
105  */
106 static void set_bios_mode(void)
107 {
108 #ifdef CONFIG_X86_64
109         struct biosregs ireg;
110 
111         initregs(&ireg);
112         ireg.ax = 0xec00;
113         ireg.bx = 2;
114         intcall(0x15, &ireg, NULL);
115 #endif
116 }
117 
118 static void init_heap(void)
119 {
120         char *stack_end;
121 
122         if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
123                 stack_end = (char *) (current_stack_pointer - STACK_SIZE);
124                 heap_end = (char *) ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
125                 if (heap_end > stack_end)
126                         heap_end = stack_end;
127         } else {
128                 /* Boot protocol 2.00 only, no heap available */
129                 puts("WARNING: Ancient bootloader, some functionality may be limited!\n");
130         }
131 }
132 
133 void main(void)
134 {
135         init_default_io_ops();
136 
137         /* First, copy the boot header into the "zeropage" */
138         copy_boot_params();
139 
140         /* Initialize the early-boot console */
141         console_init();
142         if (cmdline_find_option_bool("debug"))
143                 puts("early console in setup code\n");
144 
145         /* End of heap check */
146         init_heap();
147 
148         /* Make sure we have all the proper CPU support */
149         if (validate_cpu()) {
150                 puts("Unable to boot - please use a kernel appropriate for your CPU.\n");
151                 die();
152         }
153 
154         /* Tell the BIOS what CPU mode we intend to run in */
155         set_bios_mode();
156 
157         /* Detect memory layout */
158         detect_memory();
159 
160         /* Set keyboard repeat rate (why?) and query the lock flags */
161         keyboard_init();
162 
163         /* Query Intel SpeedStep (IST) information */
164         query_ist();
165 
166         /* Query APM information */
167 #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
168         query_apm_bios();
169 #endif
170 
171         /* Query EDD information */
172 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
173         query_edd();
174 #endif
175 
176         /* Set the video mode */
177         set_video();
178 
179         /* Do the last things and invoke protected mode */
180         go_to_protected_mode();
181 }
182 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php