]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - grubload/multiboot_c.c
Merge branch 'master' of /storage/git/netwatch
[netwatch.git] / grubload / multiboot_c.c
... / ...
CommitLineData
1#include "console.h"
2#include <io.h>
3#include <smram.h>
4
5#define INFO_SIGNATURE 0x5754454E
6
7extern char _binary_realmode_bin_start[];
8extern int _binary_realmode_bin_size;
9
10struct mb_info
11{
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
28struct info_section
29{
30 unsigned int signature;
31 void (*firstrun)();
32};
33
34void panic(const char *msg)
35{
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;
45 unsigned short *grubptr = (unsigned short *)0x7CFE;
46 unsigned char smramc;
47 int i;
48
49 void (*realmode)() = (void (*)()) 0x4000;
50
51 show_cursor();
52 puts("NetWatch loader\n");
53
54 if (magic != 0x2BADB002)
55 panic("Bootloader was not multiboot compliant; cannot continue.");
56
57 for (i = 0; i < mbinfo->mod_cnt; i++)
58 {
59 puts("Module found:\n");
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");
63 }
64
65 if (mbinfo->mod_cnt != 1)
66 panic("Expected exactly one module; cannot continue.");
67
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
72 outl(0x830, inl(0x830) & ~0x1); /* turn off SMIs */
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);
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)
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)
91 {
92 smram_restore_state(old_smramc); /* Restore so that video ram is touchable again. */
93 panic("Info section signature mismatch.");
94 }
95
96 info->firstrun();
97 smram_restore_state(old_smramc);
98
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");
107
108 puts("Now returning to real mode.\n");
109 memcpy(0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size);
110 realmode(); // goodbye!
111}
This page took 0.026627 seconds and 4 git commands to generate.