76{
77
78
79
80
81
82
83
84 Multiboot * mbi =
static_cast<Multiboot *
>(
Ptab::remap (mbi_addr));
85
86 if (!(mbi->flags & Multiboot::MODULES) || (mbi->mods_count < 1))
87 panic ("No multiboot modules\n");
88
89
90 Multiboot_module mod = *
static_cast<Multiboot_module *
>(
Ptab::remap (mbi->mods_addr));
91
92
93 Eh *eh =
static_cast<Eh *
>(
Ptab::remap(mod.mod_start));
94 if (eh->ei_magic != 0x464c457f || eh->ei_class != 1 || eh->ei_data != 1 || eh->type != 2 || eh->machine != 3)
95 panic ("No ELF");
96
97 current->regs.edx = eh->entry;
98
99 unsigned count = eh->ph_count;
100
101 Ph *ph =
static_cast<Ph *
>(
Ptab::remap(mod.mod_start + eh->ph_offset));
102
103 for (unsigned i = 0; i < count; i++, ph++) {
104
105 if (ph->type == Ph::PT_LOAD) {
106
107 if (ph->f_size > ph->m_size || ph->v_addr % PAGE_SIZE != ph->f_offs % PAGE_SIZE)
108 panic ("Bad ELF");
109
110 mword attr;
111 if (ph->flags & Ph::PF_W)
112 attr = Ptab::PRESENT | Ptab::USER | Ptab::RW;
113 else
114 attr = Ptab::PRESENT | Ptab::USER;
115
116 mword virt = align_dn(ph->v_addr, PAGE_SIZE);
117 mword phys = align_dn(ph->f_offs + mod.mod_start, PAGE_SIZE);
118 mword fsize = align_up(ph->v_addr % PAGE_SIZE + ph->f_size, PAGE_SIZE);
119 mword msize = align_up(ph->v_addr % PAGE_SIZE + ph->m_size, PAGE_SIZE);
120
121 while (msize > 0) {
122 if (fsize == 0) {
123 void *page = Kalloc::allocator.
alloc_page (1, Kalloc::FILL_0);
124 if (!page)
125 panic ("Not enough memory\n");
127 }
129 panic ("Not enough memory\n");
130 phys += PAGE_SIZE;
131 virt += PAGE_SIZE;
132 msize -= PAGE_SIZE;
133 fsize -= fsize ? PAGE_SIZE : 0;
134 }
135
136
137 if ((ph->m_size > ph->f_size) && (attr & Ptab::RW))
138 memset(reinterpret_cast<void*>(ph->v_addr + ph->f_size),
139 0x00, ph->m_size - ph->f_size);
140
141 Ec::break_min = Ec::break_current = virt;
142 }
143 }
144
145
146 void *stack = Kalloc::allocator.
alloc_page (1, Kalloc::FILL_0);
147 if (!stack)
148 panic ("Not enough memory\n");
149
150
152 Ptab::PRESENT | Ptab::RW | Ptab::USER))
153 panic ("Not enough memory\n");
154
155 current->regs.ecx = 0xc0000000;
156
157 current->next = current;
158}
static mword virt2phys(void *)
Return the physical address that is mapped from the virtual address virt (opposite of phys2virt).
Definition kalloc.cc:98
void * alloc_page(unsigned count, Fill fill=NOFILL)
Allocate count virtually contiguous pages and optionally fill them with 0x00 or 0xFF.
Definition kalloc.cc:46
static void * remap(mword phys)
Maps the passed physical address to the fixed virtual address REMAP_SADDR as a single 4MB page.
Definition ptab.cc:65
static bool insert_mapping(mword virt, mword phys, mword attr)
Inserts a 4 KB mapping into the page table.
Definition ptab.cc:20