32#ifndef PEDIGREE_HOSTED_DARWIN
36#include "pedigree/kernel/BootstrapInfo.h"
37#include "pedigree/kernel/TargetInfo.h"
38#include "pedigree/kernel/compiler.h"
39#include "pedigree/kernel/processor/hosted/FunctionProfile.h"
40#include "pedigree/kernel/processor/hosted/smoke.h"
44HostedSmokeStage g_HostedSmokeStage = HostedSmokeNone;
46static size_t profileDivisor = 1;
48size_t hostedSyscallProfileDivisor() {
49 return profileDivisor;
52bool hostedSyscallProfileRequested() {
54 const char* value = getenv(
"PEDIGREE_HOSTED_SYSCALL_PROFILE");
55 return value && !strcmp(value,
"1");
61static void* add_ptr(
void* ptr,
size_t addend) {
62 uintptr_t ptr_u = (uintptr_t)ptr;
67extern "C" int main(
int argc,
char* argv[]) {
74 void* initrd_mapping = MAP_FAILED;
75#ifndef PEDIGREE_HOSTED_DARWIN
76 void* kernel_mapping = MAP_FAILED;
78 void* diskimage_mapping = MAP_FAILED;
79 uintptr_t* module_region = (uintptr_t*)MAP_FAILED;
80 size_t initrd_length = 0;
81#ifndef PEDIGREE_HOSTED_DARWIN
82 size_t kernel_length = 0;
84 size_t diskimage_length = 0;
85#ifndef PEDIGREE_HOSTED_DARWIN
87 Elf64_Shdr* shdrs = 0;
91 if (hostedSyscallProfileRequested()) {
92 const char* value = getenv(
"PEDIGREE_HOSTED_PROFILE_DIVISOR");
95 const unsigned long divisor = strtoul(value, &end, 10);
96 if (!*value || *end || divisor < 1 || divisor > 100000) {
97 fprintf(stderr,
"PEDIGREE_HOSTED_PROFILE_DIVISOR must be between 1 and 100000.\n");
100 profileDivisor = divisor;
104 if (argc < 2 || argc > 4) {
106 "Usage: kernel initrd "
107 "[diskimage [root|init|command|shutdown]]\n");
111#if PEDIGREE_HOSTED_FUNCTION_PROFILE
112 if (!hostedFunctionProfileInitialise()) {
118 if (!strcmp(argv[3],
"root")) {
119 g_HostedSmokeStage = HostedSmokeRoot;
120 }
else if (!strcmp(argv[3],
"init")) {
121 g_HostedSmokeStage = HostedSmokeInit;
122 }
else if (!strcmp(argv[3],
"command")) {
123 g_HostedSmokeStage = HostedSmokeCommand;
124 }
else if (!strcmp(argv[3],
"shutdown")) {
125 g_HostedSmokeStage = HostedSmokeShutdown;
127 fprintf(stderr,
"Unknown hosted smoke stage: %s\n", argv[3]);
132 fprintf(stderr,
"Hosted runtime: %s; heap: %s\n",
133 HAS_ADDRESS_SANITIZER ?
"AddressSanitizer" :
"unsanitized",
134 HOSTED_SYSTEM_MALLOC ?
"system malloc" :
"Pedigree SlamAllocator");
135 fprintf(stderr,
"Pedigree is starting...\n");
138 initrd = open(argv[1], O_RDONLY);
140 fprintf(stderr,
"Can't open initrd: %s\n", strerror(errno));
144#ifndef PEDIGREE_HOSTED_DARWIN
146 kernel = open(argv[0], O_RDONLY);
148 fprintf(stderr,
"Can't open kernel: %s\n", strerror(errno));
154 r = fstat(initrd, &st);
156 fprintf(stderr,
"Can't stat initrd: %s\n", strerror(errno));
159 initrd_length = st.st_size;
160 initrd_mapping = mmap(0, initrd_length, PROT_READ, MAP_PRIVATE, initrd, 0);
161 if (initrd_mapping == MAP_FAILED) {
162 fprintf(stderr,
"Can't map initrd: %s\n", strerror(errno));
165 fprintf(stderr,
"initrd is at %p\n", initrd_mapping);
167#ifndef PEDIGREE_HOSTED_DARWIN
168 r = fstat(kernel, &st);
170 fprintf(stderr,
"Can't stat kernel: %s\n", strerror(errno));
173 kernel_length = st.st_size;
174 kernel_mapping = mmap(0, kernel_length, PROT_READ | PROT_WRITE, MAP_PRIVATE, kernel, 0);
175 if (kernel_mapping == MAP_FAILED) {
176 fprintf(stderr,
"Can't map kernel: %s\n", strerror(errno));
179 fprintf(stderr,
"kernel is at %p\n", kernel_mapping);
184 MAP_PRIVATE | MAP_ANON, -1, 0);
185 if (module_region == MAP_FAILED) {
186 fprintf(stderr,
"Can't map module information region: %s\n", strerror(errno));
189 fprintf(stderr,
"module region is at %p\n", module_region);
193 module_region[0] =
reinterpret_cast<uintptr_t
>(initrd_mapping);
194 module_region[1] =
reinterpret_cast<uintptr_t
>(initrd_mapping) + initrd_length;
196 bs.mods_addr =
reinterpret_cast<uintptr_t
>(module_region);
200 diskimage = open(argv[2], O_RDWR);
202 fprintf(stderr,
"Can't open disk image: %s\n", strerror(errno));
206 r = fstat(diskimage, &st);
208 fprintf(stderr,
"Can't stat disk image: %s\n", strerror(errno));
212 diskimage_length = st.st_size;
213 diskimage_mapping = mmap(0, diskimage_length, PROT_READ | PROT_WRITE,
214 MAP_PRIVATE | MAP_NORESERVE, diskimage, 0);
215 if (diskimage_mapping == MAP_FAILED) {
216 fprintf(stderr,
"Can't map disk image: %s\n", strerror(errno));
219 fprintf(stderr,
"disk image is at %p\n", diskimage_mapping);
223 module_region[4] =
reinterpret_cast<uintptr_t
>(diskimage_mapping);
224 module_region[5] =
reinterpret_cast<uintptr_t
>(diskimage_mapping) + diskimage_length;
227#ifndef PEDIGREE_HOSTED_DARWIN
229 ehdr =
reinterpret_cast<Elf64_Ehdr*
>(kernel_mapping);
230 bs.shndx = ehdr->e_shstrndx;
231 bs.num = ehdr->e_shnum;
232 bs.size = ehdr->e_shentsize;
233 bs.addr =
reinterpret_cast<uintptr_t
>(kernel_mapping) + ehdr->e_shoff;
236 shdrs =
reinterpret_cast<Elf64_Shdr*
>(bs.addr);
237 for (uint32_t i = 1; i < bs.num; ++i) {
238 if (shdrs[i].sh_addr)
241 shdrs[i].sh_addr = shdrs[i].sh_offset +
reinterpret_cast<uintptr_t
>(kernel_mapping);
245 fprintf(stderr,
"Running main(), with mappings:\n");
246#ifndef PEDIGREE_HOSTED_DARWIN
247 fprintf(stderr,
" kernel: %p -> %p\n", kernel_mapping, add_ptr(kernel_mapping, kernel_length));
249 fprintf(stderr,
" kernel: Mach-O process symbols\n");
251 fprintf(stderr,
" diskimage: %p -> %p\n", diskimage_mapping,
252 add_ptr(diskimage_mapping, diskimage_length));
253 fprintf(stderr,
" modules: %p -> %p\n", module_region,
255 fprintf(stderr,
" initrd: %p -> %p\n", initrd_mapping, add_ptr(initrd_mapping, initrd_length));
258 bs.flags |= BOOTSTRAP_FLAG_MODULES;
259#ifndef PEDIGREE_HOSTED_DARWIN
260 bs.flags |= BOOTSTRAP_FLAG_ELF;
264 fprintf(stderr,
"main() returned, cleaning up...\n");
270 if (module_region != MAP_FAILED)
272 if (diskimage_mapping != MAP_FAILED)
273 munmap(diskimage_mapping, diskimage_length);
274#ifndef PEDIGREE_HOSTED_DARWIN
275 if (kernel_mapping != MAP_FAILED)
276 munmap(kernel_mapping, kernel_length);
278 if (initrd_mapping != MAP_FAILED)
279 munmap(initrd_mapping, initrd_length);
static constexpr size_t getPageSize() noexcept