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

Function new_kernel_thread

kernel/src/process.rs:362–420  ·  view source on GitHub ↗

Start a new kernel thread by adding it to the process table. This won't run immediately, but will run when the scheduler next switches to it. Inputs ------ function : fn() -> () The new thread entry point Returns ------- The TID of the new thread Note: returning Box to be scheduled leads to panic in VirtAddr::new(). Cause unknown, exposing memory/stack bug?

(
    function: fn()->(),
    mut handles: Vec<Arc<RwLock<Rendezvous>>>
)

Source from the content-addressed store, hash-verified

360/// exposing memory/stack bug?
361///
362pub fn new_kernel_thread(
363 function: fn()->(),
364 mut handles: Vec<Arc<RwLock<Rendezvous>>>
365) -> u64 {
366
367 // Create a new process table entry
368 //
369 // Note this is first created on the stack, then moved into a Box
370 // on the heap.
371 let new_thread = {
372 // Allocate both "user" and kernel stacks in kernel memory
373 let kernel_stack = Vec::with_capacity(KERNEL_STACK_SIZE + USER_STACK_SIZE);
374 let kernel_stack_start = VirtAddr::from_ptr(kernel_stack.as_ptr());
375 let kernel_stack_end = (kernel_stack_start + KERNEL_STACK_SIZE).as_u64();
376 let user_stack_end = kernel_stack_end + (USER_STACK_SIZE as u64);
377
378 Box::new(Thread {
379 tid: unique_id(),
380 process: Arc::new(RwLock::new(Process {
381 page_table_physaddr: 0,
382 // Wrap each handle in an Option
383 handles:handles.drain(..)
384 .map(|h| Some(h)).collect(),
385 // Empty set of mount paths
386 mounts: vfs::VFS::new()
387 })),
388 page_table_physaddr: 0, // Don't need to switch PT
389 kernel_stack,
390 // Note that stacks move backwards, so SP points to the end
391 kernel_stack_end,
392 user_stack_end,
393 // Push a Context struct on the kernel stack
394 context: kernel_stack_end - INTERRUPT_CONTEXT_SIZE as u64,
395 })
396 };
397
398 // Cast context address to Context struct
399 let context = new_thread.context_mut();
400
401 // Set the instruction pointer
402 context.rip = function as usize;
403
404 // Set flags
405 context.rflags = 0x200;
406
407 // Set segment selector flags
408 let (code_selector, data_selector) = gdt::get_kernel_segments();
409 context.cs = code_selector.0 as usize;
410 context.ss = data_selector.0 as usize;
411
412 // The kernel thread has its own stack
413 // Note: Need to point to the end of the memory region
414 // because the stack moves down in memory
415 context.rsp = new_thread.user_stack_end as usize;
416
417 let tid = new_thread.tid;
418 schedule_thread(new_thread);
419 tid

Callers 1

kernel_entryFunction · 0.85

Calls 6

unique_idFunction · 0.85
get_kernel_segmentsFunction · 0.85
schedule_threadFunction · 0.85
as_ptrMethod · 0.80
context_mutMethod · 0.80
as_u64Method · 0.45

Tested by

no test coverage detected