]> Joshua Wise's Git repositories - netwatch.git/blame - grubload/multiboot_c.c
put the stack in bss to save space on disk
[netwatch.git] / grubload / multiboot_c.c
CommitLineData
9b8c947b 1#include "console.h"
60a917ef 2#include <io.h>
c34aba05 3#include <smram.h>
9b8c947b 4
e5d94488
JP
5#define INFO_SIGNATURE 0x5754454E
6
c4a16564
JW
7extern char _binary_realmode_bin_start[];
8extern int _binary_realmode_bin_size;
9
9b8c947b 10struct mb_info
56553b73 11{
9b8c947b
JW
12 unsigned long flags;
13 unsigned long mem_lower, mem_upper;
14 unsigned long boot_dev;
15 char *cmdline;
16 unsigned long mod_cnt;
17 struct mod_info *mods;
18};
19
20struct mod_info
21{
22 void *mod_start;
23 void *mod_end;
24 char *mod_string;
25 void *reserved;
26};
27
e5d94488
JP
28struct info_section
29{
30 unsigned int signature;
31 void (*firstrun)();
32};
33
e997a89b 34void panic(const char *msg)
9b8c947b 35{
e997a89b
JW
36 puts("PANIC: ");
37 puts(msg);
38 puts("\nSystem halted\n");
39 while(1) asm("hlt");
40}
41
42void c_start(unsigned int magic, struct mb_info *mbinfo)
43{
44 struct mod_info *mods = mbinfo->mods;
7e16b8e6 45 unsigned short *grubptr = (unsigned short *)0x7CFE;
60a917ef 46 unsigned char smramc;
9b8c947b
JW
47 int i;
48
7e16b8e6 49 void (*realmode)() = (void (*)()) 0x4000;
c4a16564 50
9b8c947b 51 show_cursor();
81148fa1
JW
52 puts("NetWatch loader\n");
53
54 if (magic != 0x2BADB002)
e997a89b 55 panic("Bootloader was not multiboot compliant; cannot continue.");
9b8c947b 56
e997a89b 57 for (i = 0; i < mbinfo->mod_cnt; i++)
9b8c947b 58 {
81148fa1 59 puts("Module found:\n");
c34aba05
JP
60 puts(" Start: "); puthex(mods[i].mod_start); puts("\n");
61 puts(" Size: "); puthex(mods[i].mod_end - mods[i].mod_start); puts("\n");
62 puts(" Name: "); puts(mods[i].mod_string); puts("\n");
9b8c947b 63 }
c4a16564 64
e997a89b
JW
65 if (mbinfo->mod_cnt != 1)
66 panic("Expected exactly one module; cannot continue.");
d56898ee 67
60a917ef
JW
68 puts("Current USB state is: "); puthex(pci_read16(0, 31, 2, 0xC0)); puts(" "); puthex(pci_read16(0, 31, 4, 0xC0)); puts("\n");
69 puts("Current SMI state is: "); puthex(inl(0x830)); puts("\n");
70 puts("Current SMRAMC state is: "); puthex(pci_read8(0, 0, 0, 0x70)); puts("\n");
71
81148fa1 72 outl(0x830, inl(0x830) & ~0x1); /* turn off SMIs */
60a917ef
JW
73
74 /* Try really hard to shut up USB_LEGKEY. */
75 pci_write16(0, 31, 2, 0xC0, pci_read16(0, 31, 2, 0xC0));
76 pci_write16(0, 31, 2, 0xC0, 0);
77 pci_write16(0, 31, 4, 0xC0, pci_read16(0, 31, 4, 0xC0));
78 pci_write16(0, 31, 4, 0xC0, 0);
c34aba05
JP
79
80
81 /* Open the SMRAM aperture and load our ELF. */
82 smram_state_t old_smramc = smram_save_state();
83
84 if (smram_aseg_set_state(SMRAM_ASEG_OPEN) != 0)
e997a89b
JW
85 panic("Opening SMRAM failed; cannot load ELF.");
86
87 load_elf(mods[0].mod_start, mods[0].mod_end - mods[0].mod_start);
88
89 struct info_section * info = (struct info_section *)0x10000;
90 if (info->signature != INFO_SIGNATURE)
c34aba05 91 {
e997a89b
JW
92 smram_restore_state(old_smramc); /* Restore so that video ram is touchable again. */
93 panic("Info section signature mismatch.");
c34aba05
JP
94 }
95
e997a89b
JW
96 info->firstrun();
97 smram_restore_state(old_smramc);
98
60a917ef
JW
99 puts("Waiting for a bit before returning to real mode...");
100 for (i=0; i<0x500000; i++)
101 {
102 if ((i % 0x100000) == 0)
103 puts(".");
104 inb(0x80);
105 }
106 puts("\n");
d56898ee 107
c4a16564
JW
108 puts("Now returning to real mode.\n");
109 memcpy(0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size);
86c89e89 110 realmode(); // goodbye!
56553b73 111}
This page took 0.038499 seconds and 4 git commands to generate.