The Pedigree Project  0.1
system/boot/mips/main.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "Elf32.h"
21 
22 #include "autogen.h"
23 
24 #define LOAD_ADDR 0x80200000
25 extern int ByteSet(void *buf, int c, size_t len);
26 struct BootstrapStruct_t
27 {
28  // If we are passed via grub, this information will be completely different
29  // to via the bootstrapper.
30  uint32_t flags;
31 
32  uint32_t mem_lower;
33  uint32_t mem_upper;
34 
35  uint32_t boot_device;
36 
37  uint32_t cmdline;
38 
39  uint32_t mods_count;
40  uint32_t mods_addr;
41 
42  /* ELF information */
43  uint32_t num;
44  uint32_t size;
45  uint32_t addr;
46  uint32_t shndx;
47 
48  uint32_t mmap_length;
49  uint32_t mmap_addr;
50 
51  uint32_t drives_length;
52  uint32_t drives_addr;
53 
54  uint32_t config_table;
55 
56  uint32_t boot_loader_name;
57 
58  uint32_t apm_table;
59 
60  uint32_t vbe_control_info;
61  uint32_t vbe_mode_info;
62  uint32_t vbe_mode;
63  uint32_t vbe_interface_seg;
64  uint32_t vbe_interface_off;
65  uint32_t vbe_interface_len;
66 } __attribute__((packed));
67 
68 void writeChar(char c)
69 {
70  unsigned int *p = reinterpret_cast<unsigned int *>(0x91100004);
71  *p = static_cast<unsigned int>(c);
72 }
73 
74 void writeStr(const char *str)
75 {
76  char c;
77  while ((c = *str++))
78  writeChar(c);
79 }
80 extern "C" int
81 __start(char argc, char **argv, char **env, unsigned int ramsize);
82 extern "C" int start()
83 {
84  asm volatile("li $sp, 0x800F0000");
85  // Disable interrupts.
86  asm volatile("mfc0 $t0, $12"); // get SR
87  asm volatile("addi $t1, $zero, 0x1"); // Set $t1 = 1
88  asm volatile("and $t0, $t0, $t1"); // $t0 = $t0 & 0x1
89  asm volatile("mtc0 $t0, $12"); // set SR.
90  asm volatile("j __start");
91 }
92 
93 extern "C" int __start(char argc, char **argv, char **env, unsigned int ramsize)
94 {
95  Elf32 elf("kernel");
96  elf.load((uint8_t *) file, 0);
97  elf.writeSections();
98  int (*main)(struct BootstrapStruct_t *) =
99  (int (*)(struct BootstrapStruct_t *)) elf.getEntryPoint();
100 
101  struct BootstrapStruct_t bs;
102 
103  ByteSet(&bs, 0, sizeof(bs));
104  bs.shndx = elf.m_pHeader->shstrndx;
105  bs.num = elf.m_pHeader->shnum;
106  bs.size = elf.m_pHeader->shentsize;
107  bs.addr = (unsigned int) elf.m_pSectionHeaders;
108 
109  bs.mem_upper = ramsize;
110 
111  // For every section header, set .addr = .offset + m_pBuffer.
112  for (int i = 0; i < elf.m_pHeader->shnum; i++)
113  {
114  elf.m_pSectionHeaders[i].addr =
115  elf.m_pSectionHeaders[i].offset + (uint32_t) elf.m_pBuffer;
116  }
117 
118  int a = main(&bs);
119  return a;
120 }
Bootstrap structure passed to the kernel entry point.