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