0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/build_bug.h>
0014
0015 #include "boot.h"
0016 #include "string.h"
0017
0018 struct boot_params boot_params __attribute__((aligned(16)));
0019
0020 struct port_io_ops pio_ops;
0021
0022 char *HEAP = _end;
0023 char *heap_end = _end;
0024
0025
0026
0027
0028
0029
0030
0031 static void copy_boot_params(void)
0032 {
0033 struct old_cmdline {
0034 u16 cl_magic;
0035 u16 cl_offset;
0036 };
0037 const struct old_cmdline * const oldcmd =
0038 absolute_pointer(OLD_CL_ADDRESS);
0039
0040 BUILD_BUG_ON(sizeof(boot_params) != 4096);
0041 memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
0042
0043 if (!boot_params.hdr.cmd_line_ptr &&
0044 oldcmd->cl_magic == OLD_CL_MAGIC) {
0045
0046 u16 cmdline_seg;
0047
0048
0049
0050
0051 if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
0052 cmdline_seg = ds();
0053 else
0054 cmdline_seg = 0x9000;
0055
0056 boot_params.hdr.cmd_line_ptr =
0057 (cmdline_seg << 4) + oldcmd->cl_offset;
0058 }
0059 }
0060
0061
0062
0063
0064
0065
0066 static void keyboard_init(void)
0067 {
0068 struct biosregs ireg, oreg;
0069 initregs(&ireg);
0070
0071 ireg.ah = 0x02;
0072 intcall(0x16, &ireg, &oreg);
0073 boot_params.kbd_status = oreg.al;
0074
0075 ireg.ax = 0x0305;
0076 intcall(0x16, &ireg, NULL);
0077 }
0078
0079
0080
0081
0082 static void query_ist(void)
0083 {
0084 struct biosregs ireg, oreg;
0085
0086
0087
0088 if (cpu.level < 6)
0089 return;
0090
0091 initregs(&ireg);
0092 ireg.ax = 0xe980;
0093 ireg.edx = 0x47534943;
0094 intcall(0x15, &ireg, &oreg);
0095
0096 boot_params.ist_info.signature = oreg.eax;
0097 boot_params.ist_info.command = oreg.ebx;
0098 boot_params.ist_info.event = oreg.ecx;
0099 boot_params.ist_info.perf_level = oreg.edx;
0100 }
0101
0102
0103
0104
0105 static void set_bios_mode(void)
0106 {
0107 #ifdef CONFIG_X86_64
0108 struct biosregs ireg;
0109
0110 initregs(&ireg);
0111 ireg.ax = 0xec00;
0112 ireg.bx = 2;
0113 intcall(0x15, &ireg, NULL);
0114 #endif
0115 }
0116
0117 static void init_heap(void)
0118 {
0119 char *stack_end;
0120
0121 if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
0122 asm("leal %P1(%%esp),%0"
0123 : "=r" (stack_end) : "i" (-STACK_SIZE));
0124
0125 heap_end = (char *)
0126 ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
0127 if (heap_end > stack_end)
0128 heap_end = stack_end;
0129 } else {
0130
0131 puts("WARNING: Ancient bootloader, some functionality "
0132 "may be limited!\n");
0133 }
0134 }
0135
0136 void main(void)
0137 {
0138 init_default_io_ops();
0139
0140
0141 copy_boot_params();
0142
0143
0144 console_init();
0145 if (cmdline_find_option_bool("debug"))
0146 puts("early console in setup code\n");
0147
0148
0149 init_heap();
0150
0151
0152 if (validate_cpu()) {
0153 puts("Unable to boot - please use a kernel appropriate "
0154 "for your CPU.\n");
0155 die();
0156 }
0157
0158
0159 set_bios_mode();
0160
0161
0162 detect_memory();
0163
0164
0165 keyboard_init();
0166
0167
0168 query_ist();
0169
0170
0171 #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
0172 query_apm_bios();
0173 #endif
0174
0175
0176 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
0177 query_edd();
0178 #endif
0179
0180
0181 set_video();
0182
0183
0184 go_to_protected_mode();
0185 }