]> Git Repo - J-linux.git/blob - arch/x86/boot/main.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / arch / x86 / boot / main.c
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 }
This page took 0.034471 seconds and 4 git commands to generate.