Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
process.c
Go to the documentation of this file.
1#include "procc/process.h"
2#include "hal/cpu/paging.h"
3#include "init/init.h"
5#include "libk/math.h"
6#include "libk/serial.h"
7#include "memory/kalloc.h"
10#include "memory/slab.h"
11#include "memory/vm_manager.h"
12#include "procc/scheduler.h"
13#include "procc/thread.h"
14#include "string.h"
15#include "sys/fd.h"
16#include "tty/tty.h"
17#include "type.h"
18#include "vfs/dentry.h"
19#include "vfs/enum.h"
20#include "vfs/vnode.h"
21#include <str.h>
22#include <sys/syscall.h>
23
24static struct slab_cache* process_cache = 0;
25static uint8_t* pid_bitmap = 0;
27__attribute__((unused)) static struct process_head process_bucket[256] = {0};
28static process_t* _process_list = 0;
29
30INIT(Process) {
31 vxCreateSlabCache(&process_cache, "process", sizeof(process_t), 0, 0);
34 vxnamei("/proc", &process_dentry);
35}
36
37// --- Core Executable Info ---
38#define AT_NULL 0
39#define AT_IGNORE 1
40#define AT_EXECFD 2 /* File descriptor from program */
41#define AT_PHDR 3 /* Program Headers Address from main executable */
42#define AT_PHENT 4 /* program heder entry size */
43#define AT_PHNUM 5 /* Program Headers num*/
44#define AT_PAGESZ 6 /* page size (4096) */
45#define AT_BASE 7 /* Base address dari interpreter (ld.so) jika ada */
46#define AT_FLAGS 8 /* Flags */
47#define AT_ENTRY 9 /* Entry point dari executable utama */
48#define AT_NOTELF 10 /* Program not ELF */
49
50#define AT_UID 11 /* Real User ID */
51#define AT_EUID 12 /* Effective User ID */
52#define AT_GID 13 /* Real Group ID */
53#define AT_EGID 14 /* Effective Group ID */
54
55// --- Hardware & Platform ---
56#define AT_PLATFORM 15 /* String CPU format (ex: "x86_64") */
57#define AT_HWCAP 16 /* Bitmask CPU capability */
58#define AT_CLKTCK 17 /* clock freq, for times() */
59
60#define AT_SECURE \
61 23 /* secure mode (boolean 1/0), used for setuid/setgid \
62 */
63#define AT_RANDOM 25 /* Pointer into 16 byte random for stack canary/ASLR */
64#define AT_EXECFN 31 /* String path name executbale file */
65#define AT_SYSINFO_EHDR 33
67#define USER_STACK_PAGES 256
68#define USER_STACK_SIZE (USER_STACK_PAGES * 4096)
70static uintptr_t elf_prepare_stack(uintptr_t stack_top_kernel,
71 uintptr_t stack_top_user, int argc,
72 char* const* argv, char* const* envp,
74 uintptr_t phdr_vaddr,
75 uintptr_t interp_base_addr) {
76 uint8_t* stack_top = (uint8_t*)stack_top_kernel;
77 uint8_t* sp_ptr = stack_top;
78
79 int envc = 0;
80 if (envp) {
81 while (envp[envc])
82 envc++;
83 }
84
85 uintptr_t* envp_user =
86 (uintptr_t*)kalloc(sizeof(uintptr_t) * (size_t)(envc + 1));
87 for (int i = envc - 1; i >= 0; i--) {
88 size_t len = strlen(envp[i]) + 1;
89 sp_ptr -= len;
90 memcopy(sp_ptr, (void*)envp[i], len);
91 envp_user[i] = stack_top_user - (uintptr_t)(stack_top - sp_ptr);
92 }
93 envp_user[envc] = 0;
94
95 uintptr_t* argv_user =
96 (uintptr_t*)kalloc(sizeof(uintptr_t) * (size_t)(argc + 1));
97 for (int i = argc - 1; i >= 0; i--) {
98 size_t len = strlen(argv[i]) + 1;
99 sp_ptr -= len;
100 memcopy(sp_ptr, (void*)argv[i], len);
101 argv_user[i] = stack_top_user - (uintptr_t)(stack_top - sp_ptr);
102 }
103 argv_user[argc] = 0;
104
105 uint8_t random_bytes[16] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE,
106 0xBA, 0xBE, 0x12, 0x34, 0x56, 0x78,
107 0x9A, 0xBC, 0xDE, 0xF0};
108 sp_ptr -= 16;
109 memcopy(sp_ptr, random_bytes, 16);
110 uintptr_t random_user_addr =
111 stack_top_user - (uintptr_t)(stack_top - sp_ptr);
112
113 uint64_t* sp = (uint64_t*)((uintptr_t)sp_ptr & ~(uintptr_t)15);
114
115 *(--sp) = 0;
116 *(--sp) = AT_NULL;
117 *(--sp) = entry_addr;
118 *(--sp) = AT_ENTRY;
119 *(--sp) = random_user_addr;
120 *(--sp) = AT_RANDOM;
121 *(--sp) = 0;
122 *(--sp) = AT_HWCAP;
123 *(--sp) = 0;
124 *(--sp) = AT_SECURE;
125 *(--sp) = 1000;
126 *(--sp) = AT_UID;
127 *(--sp) = 1000;
128 *(--sp) = AT_GID;
129 *(--sp) = 1000;
130 *(--sp) = AT_EGID;
131 *(--sp) = 1000;
132 *(--sp) = AT_EUID;
133
134 if (interp_base_addr) {
135 *(--sp) = interp_base_addr;
136 *(--sp) = AT_BASE;
137 }
138
139 *(--sp) = 0x1000;
140 *(--sp) = AT_PAGESZ;
141 *(--sp) = ehdr->e_phnum;
142 *(--sp) = AT_PHNUM;
143 *(--sp) = ehdr->e_phentsize;
144 *(--sp) = AT_PHENT;
145 *(--sp) = phdr_vaddr;
146 *(--sp) = AT_PHDR;
147
148 *(--sp) = 0;
149 for (int i = envc - 1; i >= 0; i--) {
150 *(--sp) = envp_user[i];
151 }
152
153 *(--sp) = 0;
154 for (int i = argc - 1; i >= 0; i--) {
155 *(--sp) = argv_user[i];
156 }
157
158 *(--sp) = (uint64_t)argc;
159
160 serial2_printf("=== STACK & EXEC DEBUG ===\n");
161 serial2_printf("user_rsp = 0x%x\n", stack_top_user);
162 serial2_printf("argc = %d\n", *(uint64_t*)sp);
163 serial2_printf("argv[0] = 0x%x\n", *((uint64_t*)sp + 1));
164 serial2_printf("main_entry = 0x%x\n", entry_addr);
165 serial2_printf("interp_entry = 0x%x\n", interp_base_addr);
166 serial2_printf("==========================\n");
167
168 kfree2(envp_user);
169 kfree2(argv_user);
170
171 return stack_top_user - (uintptr_t)(stack_top - (uint8_t*)sp);
172}
174int execve(const char* path, char* const* argv, char* const* envp) {
175 serial2_printf("exec proccess %s ... \n", path);
176
177 dentry_ptr loaded_file_dentry;
178 if (resolve_dentry((char*)path, 0, &loaded_file_dentry, 0) != VFS_OK) {
179 LOG2_ERROR("Proccess", "executbale %s not found", path);
180 return -1;
181 }
182
183 if (loaded_file_dentry) {
184 serial2_printf("found %s (size %d kb) \n",
185 loaded_file_dentry->name->c_str,
186 loaded_file_dentry->vnode->size / 1024);
187 }
188
191 serial2_printf("new page pml4 %p\n", (uintptr_t)page);
192
193 size_t size = 0;
194 uint8_t* file_buffer = 0;
195 if (loaded_file_dentry->vnode->type == VNODE_TYPE_FILE) {
196 size = loaded_file_dentry->vnode->size;
197 file_buffer = (uint8_t*)kalloc(size);
198 if (!file_buffer) {
199 dentry_put(loaded_file_dentry);
200 return -1;
201 }
202
203 auto ops = (vops_file_t*)loaded_file_dentry->vnode->ops;
204 ops->read(loaded_file_dentry->vnode, file_buffer, size, 0);
205 } else if (loaded_file_dentry->vnode->type == VNODE_TYPE_LNK) {
206 char link_path[255];
207 auto link_ops = (vops_lnk_t*)loaded_file_dentry->vnode->ops;
208 link_ops->readlink(loaded_file_dentry->vnode, link_path, 255);
209
210 if (resolve_dentry(link_path, loaded_file_dentry->parent,
211 &loaded_file_dentry, 0) != VFS_OK) {
212 dentry_put(loaded_file_dentry);
213 return -1;
214 }
215
216 size = loaded_file_dentry->vnode->size;
217 file_buffer = (uint8_t*)kalloc(size);
218 if (!file_buffer) {
219 dentry_put(loaded_file_dentry);
220 return -1;
221 }
222
223 auto ops = (vops_file_t*)loaded_file_dentry->vnode->ops;
224 ops->read(loaded_file_dentry->vnode, file_buffer, size, 0);
225
226 } else {
227 LOG2_ERROR("PROCESS", "unsupported file type");
228 dentry_put(loaded_file_dentry);
229 return -1;
230 }
231
232 Elf64_Ehdr ehdr;
233 memcopy(&ehdr, (void*)file_buffer, sizeof(Elf64_Ehdr));
234
235 // TODO: validate elf
236 if (ehdr.e_ident[0] != ELFMAG0 || ehdr.e_ident[1] != ELFMAG1 ||
237 ehdr.e_ident[2] != ELFMAG2 || ehdr.e_ident[3] != ELFMAG3) {
238 LOG2_ERROR("PROCESS", "invalid elf file");
239 kfree2(file_buffer);
240 dentry_put(loaded_file_dentry);
241 return -1;
242 }
243
244 size_t loaded_size = elf_count_load_size(file_buffer);
245 LOG_INFO("PROCESS", "loaded size %d (%d kb)", loaded_size,
246 loaded_size / 1024);
247 size_t size_4k = ALIGN_UP(1 + loaded_size, BLOCK_SIZE) / BLOCK_SIZE;
248
251 LOG_INFO("PROCESS", "executable %s has base addr at 0x%x", path,
252 base_addr);
253
254 LOG2_INFO("PROCESS", "found executable type is %d", ehdr.e_type);
255 if (ehdr.e_type != ET_DYN && ehdr.e_type != ET_EXEC) {
256 LOG2_ERROR("PROCESS", "wrong elf type");
257 return -2;
258 }
259
260 if (ehdr.e_type == ET_EXEC)
261 base_addr = 0;
262
263 elf_section_map sh_map = {0};
264 elf_section_map_all(file_buffer, &sh_map);
265
266 LOG2_INFO("ELF", "version : %d, ph num : %d", ehdr.e_version,
267 ehdr.e_phnum);
268 LOG2_INFO("ELF", "entry : 0x%x", ehdr.e_entry);
269 serial_trace("phdr count %d\n", ehdr.e_phnum);
270
271 uintptr_t base_vaddr = 0;
272 Elf64_Phdr* phdr = ELF_PTR(Elf64_Phdr, file_buffer, ehdr.e_phoff);
273 for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
274 Elf64_Phdr* p = ELF_PTR(Elf64_Phdr, phdr, i * ehdr.e_phentsize);
275 if (p->p_vaddr > 0) {
276 if (!base_vaddr)
277 base_vaddr = p->p_vaddr;
278 else
279 base_vaddr = min(base_vaddr, p->p_vaddr);
280 }
281 }
282
283 // find interp
284 dentry_ptr interp_dentry = 0;
285
286 for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
287 Elf64_Phdr* p = ELF_PTR(Elf64_Phdr, phdr, i * ehdr.e_phentsize);
288 if (p->p_type == PT_INTERP) {
289 char* interp_path = (char*)(file_buffer + p->p_offset);
290
291 auto interp_path_ = str(interp_path);
292 serial2_printf("found interp %s\n",
293 interp_path_->c_str);
294 if (resolve_dentry(interp_path_->c_str, 0,
295 &interp_dentry, 0) != VFS_OK) {
297 "error: dynamic linker not found..\n");
298 str_release(interp_path_);
299 return -1;
300 }
301 str_release(interp_path_);
302 break;
303 }
304 }
305
306 struct elf_load_mmap_table* mmap_table =
308 sizeof(struct elf_load_mmap_table) * ehdr.e_phnum);
309
310 auto l = elf_load(page, file_buffer, base_addr, base_addr, mmap_table);
311 serial2_printf("loaded size %d kb\n", l / 1024);
312
313 uintptr_t temporary_base = 0;
314 for (int i = 0; i < ehdr.e_phnum; i++) {
315 if (mmap_table[i].mapped) {
316 temporary_base = mmap_table[i].vaddr;
317 break;
318 }
319 }
320
321 // find heap start
323 {
324 for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
325 Elf64_Phdr* p =
326 ELF_PTR(Elf64_Phdr, phdr, i * ehdr.e_phentsize);
327 if (p->p_type == PT_LOAD) {
328 auto end = base_addr + p->p_vaddr + p->p_memsz;
329 if (end > heap_start)
330 heap_start = end;
331 }
332 }
333 heap_start = ALIGN_UP(heap_start, 0x1000);
334
335 serial2_printf("heap start at 0x%x\n", heap_start);
336 }
337
338 serial2_printf("temporary_base 0x%x -> base 0x%x\n", temporary_base,
339 base_addr);
340 if (!temporary_base) {
341 serial2_printf("error temporary addr must be not empty\n");
342 kfree2(mmap_table);
343 dentry_put(loaded_file_dentry);
344 return -2;
345 }
346
347 GnuHashHeader gnu_hash;
348 Elf64_Shdr* gnu_hash_sym = sh_map.gnuhash;
349 elf_gnu_hash_parse(&gnu_hash, gnu_hash_sym, file_buffer);
350
351 Elf64_Dyn* dyn = elf_get_phdr_dynamic(file_buffer);
352 if (dyn && !interp_dentry) {
353 LOG_INFO("VOXMO", "dynamic section found at 0x%x", dyn);
354 elf_dynamic_map dyn_map = {0};
355 elf_dyn_map_all(dyn, file_buffer, &dyn_map);
356 LOG_INFO("VOXMO", "strtab found at 0x%x", dyn_map.strtab);
357 LOG_INFO("VOXMO", "needed size %d", dyn_map.needed.size);
358 elf_relocate_dyn(&dyn_map, temporary_base, base_addr, &gnu_hash,
359 0, mmap_table, ehdr.e_phnum);
360 }
361
362 serial2_printf("base vaddr %x %x\n", base_vaddr,
363 (ehdr.e_entry - base_vaddr));
364
365 auto entry_addr =
366 (ehdr.e_type == ET_EXEC) ? ehdr.e_entry : ehdr.e_entry + base_addr;
367
368 // ld handle
369 // TODO: will be refactor
370 uintptr_t interp_base_addr = 0;
371 uintptr_t interp_entry_addr = 0;
372 Elf64_Ehdr interp_ehdr;
373
374 struct elf_load_mmap_table* interp_mmap_table = 0;
375
376 if (interp_dentry) {
377 // handle interp
378 auto interp_file_size = interp_dentry->vnode->size;
379 serial2_printf("interp found %s size %d\n",
380 interp_dentry->name->c_str, interp_file_size);
381
382 dentry_ptr interp_link_dentry = 0;
383
384 if (interp_dentry->vnode->type == VNODE_TYPE_LNK) {
385 char interp_link_path[255];
386 auto interp_ops =
387 (vops_lnk_t*)interp_dentry->vnode->ops;
388 interp_ops->readlink(interp_dentry->vnode,
389 interp_link_path, 255);
390 serial2_printf("link path %s\n", interp_link_path);
391
392 if (resolve_dentry(interp_link_path, 0,
393 &interp_link_dentry, 0) != VFS_OK) {
394 serial2_printf("failed resolve %s\n",
395 interp_link_path);
396 return -1;
397 }
398 }
399 auto ld_so_size = interp_link_dentry->vnode->size;
400 uint8_t* ld_so_buffer = (uint8_t*)kalloc(ld_so_size);
401 if (!ld_so_buffer) {
402 LOG2_ERROR("PROCESS", "unable to alloc %d kb",
403 ld_so_size / 1024);
404 dentry_put(interp_dentry);
405 return -1;
406 }
407
408 auto ld_so_ops = (vops_file_t*)interp_link_dentry->vnode->ops;
409 if (!ld_so_ops) {
410 LOG_ERROR("PROCESS", "ops is null");
411 kfree2(ld_so_buffer);
412 dentry_put(interp_dentry);
413 return -1;
414 }
415
416 ld_so_ops->read(interp_link_dentry->vnode, ld_so_buffer,
417 ld_so_size, 0);
418 serial2_printf("interp file size %d kb\n",
419 (uint32_t)ld_so_size / 1024);
420
421 memcopy(&interp_ehdr, (void*)ld_so_buffer, sizeof(Elf64_Ehdr));
422
423 size_t ld_so_size_4k =
424 ALIGN_UP(1 + ld_so_size, BLOCK_SIZE) / BLOCK_SIZE;
425
426 interp_base_addr = vma_lookup_free_vaddr(
427 get_kernel_vmm_page(), VMA_REGION_PROCESS, ld_so_size_4k);
428 LOG_INFO("PROCESS", "interp %s has base addr at 0x%x",
429 interp_dentry->name->c_str, interp_base_addr);
430
431 interp_mmap_table = (struct elf_load_mmap_table*)kalloc(
432 sizeof(struct elf_load_mmap_table) * interp_ehdr.e_phnum);
433
434 auto ll = elf_load(page, ld_so_buffer, interp_base_addr,
435 interp_base_addr, interp_mmap_table);
436 serial2_printf("ld.so loaded size %d kb\n", ll / 1024);
437
438 interp_entry_addr = interp_base_addr + interp_ehdr.e_entry;
439 }
440
441 // Stack setup
442 auto stack_phys = (uintptr_t)phys_base_alloc(USER_STACK_PAGES);
443 auto stack_vaddr = vma_lookup_free_vaddr(
446 stack_phys, USER_STACK_PAGES, 0b111);
447 vxMultipleMmap(paging_get_highest_page_map(), stack_vaddr, stack_phys,
448 USER_STACK_PAGES, 0b111);
449
450 uintptr_t phdr_vaddr = (ehdr.e_type == ET_EXEC)
451 ? base_vaddr + ehdr.e_phoff
452 : base_addr + ehdr.e_phoff;
453
454 int argc = 0;
455 if (argv) {
456 while (argv[argc])
457 argc++;
458 }
459
460 const char* fallback_argv[] = {path, NULL};
461 if (argc == 0) {
462 argv = (char* const*)fallback_argv;
463 argc = 1;
464 }
465
466 uintptr_t user_rsp = elf_prepare_stack(
467 stack_vaddr + USER_STACK_SIZE, USER_STACK_VADDR + 4096, argc, argv,
468 envp, &ehdr, entry_addr, phdr_vaddr, interp_base_addr);
469
470 auto entr = entry_addr;
471 if (interp_base_addr)
472 entr = interp_entry_addr;
473
475 vma_unregister(get_kernel_vmm_page(), stack_vaddr);
476
477 // end
478
479 auto thr = create_thread(page, entr, user_rsp, 1, 2, THREAD_USER);
480 auto procc = create_process(loaded_file_dentry->name->c_str, thr);
481 procc->heap_start = heap_start;
482 procc->heap_end = procc->heap_start;
483 procc->vm_lock.next_ticket = procc->vm_lock.now_serving = 0;
484
485 procc->vm_page = create_vmm_page();
486 for (int i = 0; i < ehdr.e_phnum; i++) {
487 auto mm = &mmap_table[i];
488 if (mm->mapped) {
490 "process: added to vma aligned base 0x%x\n",
491 base_addr + mm->alligned);
492 vma_register(procc->vm_page, mm->paddr,
493 base_addr + mm->alligned, mm->size);
494 }
495 }
496
497 if (interp_base_addr && interp_mmap_table) {
498 serial2_printf("interp base addr 0x%x\n", interp_base_addr);
499 for (int i = 0; i < interp_ehdr.e_phnum; i++) {
500 auto mm = &interp_mmap_table[i];
501
502 if (mm->mapped) {
503 serial_printf("process: added interp to vma "
504 "aligned base 0x%x\n",
505 interp_base_addr + mm->alligned);
506
507 vma_register(procc->vm_page, mm->paddr,
508 interp_base_addr + mm->alligned,
509 mm->size);
510 }
511 }
512 }
513
515
516 serial2_printf("process id %d\n", procc->pid);
518 "done setuping executable, now ready to sended to scheduler\n");
519
521
522 kfree2(mmap_table);
523 dentry_put(loaded_file_dentry);
524 return VFS_OK;
525}
526
527/*
528 * Internal functions
529 */
530pid_t alloc_pid(void) {
531 for (size_t i = 0; i < MAX_PID_ALLOWED / 8; i++) {
532 uint8_t byte = pid_bitmap[i];
533
534 if (byte == 0xFF)
535 continue;
536
537 uint8_t free_bit =
538 (uint8_t)__builtin_ctz((unsigned)(~byte & 0xFF));
539
540 pid_bitmap[i] |= (1u << free_bit);
541 return (pid_t)(i * 8 + free_bit);
542 }
543
544 return INVALID_PID;
545}
547void free_pid(pid_t pid) {
548 pid_t curr_byte = pid / 8;
549 uint8_t curr_bit = pid % 8;
550 pid_bitmap[curr_byte] &= ~(1 << curr_bit);
551}
553process_t* create_process(char* name, thread_t* main_thread) {
554 auto p = (process_t*)vxSlabAlloc(process_cache);
555 auto name_len = strlen(name);
556 if (name_len > 64)
557 name_len = 64;
558 strncpy(p->name, name, name_len);
559 p->name[name_len] = '\0';
560 p->pid = alloc_pid();
561
562 p->main_thread = main_thread;
563 main_thread->process = p;
564 p->exit_code = 0;
565 p->exited = false;
566 p->fdtable = alloc_fdtable();
567 p->cache.next = &p->cache;
568 p->cache.prev = &p->cache;
569
570 auto bucket_idx = p->pid % 256;
571 auto h = process_bucket[bucket_idx].first;
572 auto n = &p->cache;
573 n->next = h;
574 n->prev = NULL;
575 if (h)
576 h->prev = n;
577 process_bucket[bucket_idx].first = n;
578
579 p->next = p->prev = p;
580 if (!_process_list) {
581 _process_list = p;
582 } else {
583 struct process* tail = _process_list->prev;
584 tail->next = p;
585 p->prev = tail;
586 p->next = _process_list;
587 _process_list->prev = p;
588 }
589
590 dentry_ptr current_proc = 0;
591 resolve_dentry(itoa(p->pid, 10), process_dentry, &current_proc,
593
594 dentry_ptr current_proc_fd = 0;
595 resolve_dentry("fd", current_proc, &current_proc_fd,
597
598 auto tty_dentry = get_tty_dentry(0);
599 auto tty_vnode = tty_dentry->vnode;
600 // fd0 -> stdin (placeholder)
601 {
602 dentry_ptr fd_dentry;
603 auto next_fd = p->fdtable->next_fd++;
604 resolve_dentry(itoa(next_fd, 10), current_proc_fd, &fd_dentry,
606 fd_dentry->vnode = tty_vnode;
607
608 auto fd0 = alloc_fd();
609 fd0->vnode = tty_vnode;
610 fd0->ops = tty_vnode->ops;
611 p->fdtable->fds[next_fd] = fd0;
612 }
613 // fd1 → stdout (/dev/tty0)
614 {
615 dentry_ptr fd_dentry;
616 auto next_fd = p->fdtable->next_fd++;
617 resolve_dentry(itoa(next_fd, 10), current_proc_fd, &fd_dentry,
619 fd_dentry->vnode = tty_vnode;
620
621 auto fd1 = alloc_fd();
622 fd1->vnode = tty_vnode;
623 fd1->ops = tty_vnode->ops;
624 p->fdtable->fds[next_fd] = fd1;
625 }
626 // fd2 → stderr (TODO)
627 {
628 dentry_ptr fd_dentry;
629 auto next_fd = p->fdtable->next_fd++;
630 resolve_dentry(itoa(next_fd, 10), current_proc_fd, &fd_dentry,
632 fd_dentry->vnode = tty_vnode;
633
634 auto fd2 = alloc_fd();
635 fd2->vnode = tty_vnode;
636 fd2->ops = tty_vnode->ops;
637 p->fdtable->fds[next_fd] = fd2;
638 }
639 return p;
640}
struct SDT h
Definition acpi.h:0
kstring name
Definition dentry.h:5
struct dentry * dentry_ptr
Definition dentry.h:20
void print_dentry_tree(dentry_t *node, int depth)
Definition dentry.c:300
void dentry_put(dentry_ptr dentry)
Definition dentry.c:72
int resolve_dentry(char *path, dentry_ptr parent, dentry_ptr *out, uint8_t flag)
Resolves a path to a directory entry (dentry) with configurable start point and strictness.
int vxnamei(const char *path, dentry_ptr *out)
Resolves a file path to a directory entry (dentry).
dentry_ptr get_root_dentry()
@ CREATE_MISSING_ENTRY
Definition dentry.h:81
void * ops
Definition dev.h:2
void elf_section_map_all(uint8_t *data, elf_section_map *map)
Definition elf.c:160
size_t elf_load(volatile uintptr_t *page, uint8_t *data, uintptr_t temporary_base, uintptr_t base, struct elf_load_mmap_table *table)
Definition elf.c:261
void elf_gnu_hash_parse(GnuHashHeader *gnu_hash, Elf64_Shdr *gnu_hash_sym, uint8_t *data)
Definition elf.c:604
void elf_dyn_map_all(Elf64_Dyn *dyn, uint8_t *data, elf_dynamic_map *map)
Definition elf.c:60
Elf64_Dyn * elf_get_phdr_dynamic(uint8_t *data)
Definition elf.c:45
void elf_relocate_dyn(elf_dynamic_map *map, uintptr_t kernel_base, uintptr_t user_base, GnuHashHeader *gnu_hash, symbols_ptr_vector_t *external_syms, struct elf_load_mmap_table *table, int table_count)
Definition elf.c:534
uintptr_t elf_count_load_size(uint8_t *data)
Definition elf.c:629
#define ELFMAG0
Definition elf.h:9
#define ELFMAG3
Definition elf.h:18
@ ET_DYN
Definition elf.h:208
@ ET_EXEC
Definition elf.h:207
@ PT_INTERP
Definition elf.h:87
@ PT_LOAD
Definition elf.h:85
#define ELFMAG1
Definition elf.h:12
#define ELF_PTR(type, base, off)
Definition elf.h:346
#define ELFMAG2
Definition elf.h:15
@ VFS_OK
Definition enum.h:5
struct file_descriptor * alloc_fd()
Definition fd.c:13
struct fdtable * alloc_fdtable()
Definition fd.c:4
@ THREAD_USER
Definition thread.h:15
struct thread thread_t
Definition thread.h:29
uintptr_t entry_addr
Definition thread.h:12
typedef __attribute__
Definition msi.c:47
#define INIT(fn)
Definition init.h:26
void serial_printf(const char *fmt,...)
void serial2_printf(const char *fmt,...)
uint8_t name_len
Definition iso9660.h:19
void * kalloc(size_t size)
void kfree2(void *ptr)
uint64_t min(uint64_t a, uint64_t b)
Definition math.c:21
#define ALIGN_UP(x, align)
Definition memory_utils.h:6
size_t len
Definition oct2bin.h:7
uintptr_t page
Definition paging.c:0
page_t paging_get_highest_page_map(void)
Definition paging.c:463
page_t paging_create_page_directory()
Definition paging.c:36
void paging_setup(page_t p)
Definition paging.c:197
void paging_unmap_page(page_t page_dir, uint64_t virt)
Definition paging.c:360
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
Definition paging.c:340
uint64_t base_addr
Definition pcie.h:0
void * phys_base_alloc(uint64_t block)
#define BLOCK_SIZE
int execve(const char *path, char *const *argv, char *const *envp)
Definition process.c:173
process_t * create_process(char *name, thread_t *main_thread)
Definition process.c:552
pid_t alloc_pid(void)
Definition process.c:529
#define AT_RANDOM
Definition process.c:62
static uintptr_t elf_prepare_stack(uintptr_t stack_top_kernel, uintptr_t stack_top_user, int argc, char *const *argv, char *const *envp, Elf64_Ehdr *ehdr, uintptr_t entry_addr, uintptr_t phdr_vaddr, uintptr_t interp_base_addr)
Definition process.c:69
#define AT_EUID
Definition process.c:51
#define AT_GID
Definition process.c:52
#define AT_PHDR
Definition process.c:41
static process_t * _process_list
Definition process.c:28
void free_pid(pid_t pid)
Definition process.c:546
#define AT_PHENT
Definition process.c:42
#define USER_STACK_SIZE
Definition process.c:67
#define AT_EGID
Definition process.c:53
#define AT_PAGESZ
Definition process.c:44
#define AT_UID
Definition process.c:50
#define AT_ENTRY
Definition process.c:47
static dentry_ptr process_dentry
Definition process.c:26
#define AT_HWCAP
Definition process.c:57
#define AT_BASE
Definition process.c:45
#define AT_NULL
Definition process.c:38
#define AT_SECURE
Definition process.c:60
static struct slab_cache * process_cache
Definition process.c:24
static uint8_t * pid_bitmap
Definition process.c:25
#define AT_PHNUM
Definition process.c:43
#define USER_STACK_PAGES
Definition process.c:66
struct thread * main_thread
Definition process.h:5
#define MAX_PID_ALLOWED
Definition process.h:8
uintptr_t heap_start
Definition process.h:12
uint32_t pid_t
Definition process.h:11
#define INVALID_PID
Definition process.h:9
pid_t pid
Definition process.h:0
void attach_to_scheduler(thread_t *new_thread)
Definition scheduler.c:268
#define LOG_ERROR(mod, fmt,...)
Definition serial.h:25
#define LOG2_ERROR(mod, fmt,...)
Definition serial.h:38
#define LOG_INFO(mod, fmt,...)
Definition serial.h:20
#define serial_trace(...)
Definition serial.h:19
#define LOG2_INFO(mod, fmt,...)
Definition serial.h:33
void * vxSlabAlloc(struct slab_cache *cache)
Definition slab.c:93
void vxCreateSlabCache(struct slab_cache **cache, const char *name, const size_t obj_size, size_t alignment, const uintptr_t virt_addr)
Definition slab.c:44
char * itoa(int64_t value, int base)
Definition str.c:302
char * strncpy(char *dest, const char *src, size_t n)
size_t strlen(const char *s)
Definition str.c:105
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
void str_release(kstring str)
kstring str(const char *str)
uint16_t e_type
Definition elf.h:24
uint8_t e_ident[16]
Definition elf.h:23
uint32_t e_version
Definition elf.h:26
uint16_t e_phentsize
Definition elf.h:32
uint16_t e_phnum
Definition elf.h:33
uint64_t e_phoff
Definition elf.h:28
uint64_t e_entry
Definition elf.h:27
uint64_t p_offset
Definition elf.h:42
uint64_t p_memsz
Definition elf.h:46
uint32_t p_type
Definition elf.h:40
uint64_t p_vaddr
Definition elf.h:43
kstring name
Definition dentry.h:32
dentry_ptr parent
Definition dentry.h:34
struct vnode * vnode
Definition dentry.h:33
uint8_t * strtab
Definition elf.h:266
struct vector_uint64_t needed
Definition elf.h:267
uintptr_t vaddr
Definition elf.h:312
boolean_t mapped
Definition elf.h:316
Elf64_Shdr * gnuhash
Definition elf.h:283
char * c_str
Definition string.h:12
struct process_node * first
Definition process.h:15
struct process_node * prev
Definition process.h:20
struct process_node * next
Definition process.h:19
size_t size
Definition elf.h:263
void * ops
Definition vnode.h:64
uint8_t type
Definition vnode.h:62
size_t size
Definition vnode.h:63
thread_t * create_thread(volatile uintptr_t *page, uintptr_t entry, uintptr_t stack, uint16_t core_affinity, uint8_t priority, uint16_t flags)
Definition thread.c:41
dentry_ptr get_tty_dentry(int tty)
Definition tty.c:339
uint32_t tail
Definition tty.h:11
#define NULL
Definition type.h:76
unsigned int uint32_t
Definition type.h:19
unsigned long uintptr_t
Definition type.h:73
unsigned long uint64_t
Definition type.h:25
unsigned char uint8_t
Definition type.h:7
struct virtual_memory_page * create_vmm_page()
Definition vm_manager.c:73
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
Definition vm_manager.c:156
void vma_register(struct virtual_memory_page *page, uintptr_t phys_address, uintptr_t virt_addr, size_t size)
Definition vm_manager.c:101
void vma_unregister(struct virtual_memory_page *page, uintptr_t virt_addr)
Definition vm_manager.c:126
struct virtual_memory_page * get_kernel_vmm_page()
#define USER_STACK_VADDR
Definition vm_manager.h:9
@ VMA_REGION_A
Definition vm_manager.h:13
@ VMA_REGION_PROCESS
Definition vm_manager.h:25
@ VNODE_TYPE_FILE
Definition vnode.h:12
@ VNODE_TYPE_LNK
Definition vnode.h:19
size_t size
Definition vnode.h:3
kstring path
Definition voxmo.h:7