MCPcopy Create free account
hub / github.com/bendudson/EuraliOS / new_user_thread

Function new_user_thread

kernel/src/process.rs:463–629  ·  view source on GitHub ↗

Create a new user thread # Arguments `bin` - ELF binary containing the program. Note: This must be accessible in the kernel page tables `params` - A collection of parameters. Used so that the calling site is clearer in what parameters are being set.

(
    bin: &[u8],
    params: Params
)

Source from the content-addressed store, hash-verified

461/// * `params` - A collection of parameters. Used so that the calling
462/// site is clearer in what parameters are being set.
463pub fn new_user_thread(
464 bin: &[u8],
465 params: Params
466) -> Result<Box<Thread>, &'static str> {
467 // Check the header
468 const ELF_MAGIC: [u8; 4] = [0x7f, b'E', b'L', b'F'];
469
470 if bin[0..4] != ELF_MAGIC {
471 return Err("Expected ELF binary");
472 }
473 // Use the object crate to parse the ELF file
474 // <https://crates.io/crates/object>
475 if let Ok(obj) = object::File::parse(bin) {
476
477 // Create a user pagetable with only kernel pages
478 let (user_page_table_ptr, user_page_table_physaddr) =
479 memory::create_new_user_pagetable();
480
481 // Allocate user heap
482 if memory::create_user_ondemand_pages(
483 user_page_table_physaddr,
484 VirtAddr::new(USER_HEAP_START),
485 USER_HEAP_SIZE).is_err() {
486 return Err("Couldn't allocate on-demand pages");
487 }
488
489 return with_pagetable(user_page_table_physaddr, || {
490
491 let entry_point = obj.entry();
492
493 for segment in obj.segments() {
494 let segment_address = segment.address() as u64;
495
496 let start_address = VirtAddr::new(segment_address);
497 let end_address = start_address + segment.size() as u64;
498
499 // Check if data is in allowed range
500 if (start_address < VirtAddr::new(USER_CODE_START))
501 || (end_address >= VirtAddr::new(USER_CODE_END)) {
502 return Err("ELF segment outside allowed range");
503 }
504
505 // Allocate memory in the pagetable
506 if memory::allocate_pages(user_page_table_ptr,
507 start_address,
508 segment.size() as u64, // Size (bytes)
509 PageTableFlags::PRESENT |
510 PageTableFlags::WRITABLE |
511 PageTableFlags::USER_ACCESSIBLE).is_err() {
512 return Err("Could not allocate memory");
513 }
514 memory::switch_to_pagetable(user_page_table_physaddr);
515
516 if let Ok(data) = segment.data() {
517 if data.len() > segment.size() as usize {
518 return Err("ELF data length > segment size");
519 } else if data.len() > 0 {
520 // Copy data

Callers 2

sys_execFunction · 0.85
kernel_thread_mainFunction · 0.85

Calls 14

with_pagetableFunction · 0.85
allocate_pagesFunction · 0.85
switch_to_pagetableFunction · 0.85
allocate_user_stackFunction · 0.85
unique_idFunction · 0.85
get_user_segmentsFunction · 0.85
addressMethod · 0.80
iterMethod · 0.80
as_ptrMethod · 0.80
context_mutMethod · 0.80

Tested by

no test coverage detected