mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
Merge pull request #21 from StevenJiang1110/main
Bug fix; Add user-mode fork test codes
This commit is contained in:
commit
ee407809a6
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +1,2 @@
|
||||
src/kxos-user/hello_world/hello_world filter=lfs diff=lfs merge=lfs -text
|
||||
src/kxos-user/fork/fork filter=lfs diff=lfs merge=lfs -text
|
||||
|
@ -6,7 +6,7 @@
|
||||
#![feature(const_btree_new)]
|
||||
#![feature(cstr_from_bytes_until_nul)]
|
||||
|
||||
use kxos_frame::println;
|
||||
use kxos_frame::{info, println, task::Task};
|
||||
use process::Process;
|
||||
|
||||
extern crate alloc;
|
||||
@ -20,15 +20,26 @@ pub fn init() {
|
||||
process::fifo_scheduler::init();
|
||||
}
|
||||
|
||||
pub fn run_first_kernel_task() {
|
||||
Process::spawn_kernel_task(|| {
|
||||
println!("hello world from kernel");
|
||||
pub fn init_task() {
|
||||
println!("[kernel] Hello world from init task!");
|
||||
|
||||
let process = Process::spawn_kernel_task(|| {
|
||||
println!("[kernel] Hello world from kernel!");
|
||||
});
|
||||
info!("spawn kernel process, pid = {}", process.pid());
|
||||
|
||||
let elf_file_content = read_elf_content();
|
||||
let process = Process::spawn_from_elf(elf_file_content);
|
||||
info!("spwan user process, pid = {}", process.pid());
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
pub fn run_first_process() {
|
||||
/// first process never return
|
||||
pub fn run_first_process() -> ! {
|
||||
let elf_file_content = read_elf_content();
|
||||
Process::spawn_from_elf(elf_file_content);
|
||||
Task::spawn(init_task, None::<u8>, None).expect("Spawn first task failed");
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn read_elf_content() -> &'static [u8] {
|
||||
|
@ -1,5 +1,7 @@
|
||||
use alloc::sync::Arc;
|
||||
use kxos_frame::vm::{Vaddr, VmPerm, VmSpace};
|
||||
use kxos_frame::{
|
||||
config::PAGE_SIZE,
|
||||
vm::{Vaddr, VmPerm, VmSpace},
|
||||
};
|
||||
|
||||
use super::vm_page::VmPageRange;
|
||||
|
||||
@ -7,39 +9,41 @@ pub const USER_STACK_BASE: Vaddr = 0x0000_0000_1000_0000;
|
||||
pub const USER_STACK_SIZE: usize = 0x1000 * 16; // 64KB
|
||||
|
||||
pub struct UserStack {
|
||||
/// The low address of user stack
|
||||
pub stack_base: Vaddr,
|
||||
/// The high address of user stack
|
||||
stack_top: Vaddr,
|
||||
stack_size: usize,
|
||||
vm_space: Option<Arc<VmSpace>>,
|
||||
}
|
||||
|
||||
impl UserStack {
|
||||
/// initialize user stack on base addr
|
||||
pub const fn new(stack_base: Vaddr, stack_size: usize) -> Self {
|
||||
pub const fn new(stack_top: Vaddr, stack_size: usize) -> Self {
|
||||
Self {
|
||||
stack_base,
|
||||
stack_top,
|
||||
stack_size,
|
||||
vm_space: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// This function only work for first process
|
||||
pub const fn new_default_config() -> Self {
|
||||
Self {
|
||||
stack_base: USER_STACK_BASE,
|
||||
// add a guard page at stack top
|
||||
stack_top: USER_STACK_BASE - PAGE_SIZE,
|
||||
stack_size: USER_STACK_SIZE,
|
||||
vm_space: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// the user stack top(high address), used to setup rsp
|
||||
pub const fn stack_top(&self) -> Vaddr {
|
||||
self.stack_base + self.stack_size
|
||||
self.stack_top
|
||||
}
|
||||
|
||||
/// the user stack bottom(low address)
|
||||
const fn stack_bottom(&self) -> Vaddr {
|
||||
self.stack_top - self.stack_size
|
||||
}
|
||||
|
||||
pub fn map_and_zeroed(&self, vm_space: &VmSpace) {
|
||||
let mut vm_page_range =
|
||||
VmPageRange::new_range(self.stack_base..(self.stack_base + self.stack_size));
|
||||
let mut vm_page_range = VmPageRange::new_range(self.stack_bottom()..self.stack_top());
|
||||
let vm_perm = UserStack::perm();
|
||||
vm_page_range.map_zeroed(vm_space, vm_perm);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
// use kxos_frame::{sync::SpinLock, task::Task, user::UserSpace};
|
||||
use kxos_frame::{debug, task::Task};
|
||||
use kxos_frame::task::Task;
|
||||
|
||||
use self::task::spawn_user_task_from_elf;
|
||||
|
||||
@ -39,8 +39,7 @@ impl Process {
|
||||
F: Fn() + Send + Sync + 'static,
|
||||
{
|
||||
let pid = new_pid();
|
||||
debug!("pid = {}", pid);
|
||||
let task = Task::spawn(task_fn, None::<u8>, None).expect("spawn kernel task failed");
|
||||
let task = Task::spawn(task_fn, pid, None).expect("spawn kernel task failed");
|
||||
let exit_code = 0;
|
||||
Self {
|
||||
pid,
|
||||
@ -48,6 +47,10 @@ impl Process {
|
||||
exit_code,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pid(&self) -> usize {
|
||||
self.pid
|
||||
}
|
||||
}
|
||||
|
||||
/// create a new pid for new process
|
||||
|
@ -25,6 +25,7 @@ pub fn spawn_user_task_from_elf(elf_file_content: &[u8]) -> Arc<Task> {
|
||||
let cur = Task::current();
|
||||
let user_space = cur.user_space().expect("user task should have user space");
|
||||
let mut user_mode = UserMode::new(user_space);
|
||||
debug!("in user task");
|
||||
loop {
|
||||
let user_event = user_mode.execute();
|
||||
debug!("return from user mode");
|
||||
|
7
src/kxos-user/fork/Makefile
Normal file
7
src/kxos-user/fork/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
.PHONY: build clean run
|
||||
build: hello_world.s
|
||||
@gcc -static -nostdlib fork.s -o fork
|
||||
clean:
|
||||
@rm fork
|
||||
run: build
|
||||
@./fork
|
3
src/kxos-user/fork/fork
Executable file
3
src/kxos-user/fork/fork
Executable file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1ad189cc084511d777ec2bcb211ca7cdbfb55f00320953da71a6a37f46404dd6
|
||||
size 9488
|
52
src/kxos-user/fork/fork.s
Normal file
52
src/kxos-user/fork/fork.s
Normal file
@ -0,0 +1,52 @@
|
||||
.global _start
|
||||
|
||||
.section .text
|
||||
_start:
|
||||
call print_hello_world
|
||||
mov $57, %rax # syscall number of fork
|
||||
syscall
|
||||
|
||||
cmp $0, %rax
|
||||
je _child # child process
|
||||
jmp _parent # parent process
|
||||
_parent:
|
||||
call print_parent_message
|
||||
call exit
|
||||
_child:
|
||||
call print_child_message
|
||||
call exit
|
||||
exit:
|
||||
mov $60, %rax # syscall number of exit
|
||||
mov $0, %rdi # exit code
|
||||
syscall
|
||||
print_hello_world:
|
||||
mov $message, %rsi # address of message
|
||||
mov $message_end, %rdx
|
||||
sub %rsi, %rdx # calculate message len
|
||||
jmp _print_message
|
||||
print_parent_message:
|
||||
mov $message_parent, %rsi # address of message
|
||||
mov $message_parent_end, %rdx
|
||||
sub %rsi, %rdx # calculate message len
|
||||
jmp _print_message
|
||||
print_child_message:
|
||||
mov $message_child, %rsi # address of message
|
||||
mov $message_child_end, %rdx
|
||||
sub %rsi, %rdx # calculate message len
|
||||
jmp _print_message
|
||||
# never directly call _print_message
|
||||
_print_message:
|
||||
mov $1, %rax # syscall number of write
|
||||
mov $1, %rdi # stdout
|
||||
syscall
|
||||
ret
|
||||
.section .rodata
|
||||
message:
|
||||
.ascii "Hello, world\n"
|
||||
message_end:
|
||||
message_parent:
|
||||
.ascii "Hello world from parent\n"
|
||||
message_parent_end:
|
||||
message_child:
|
||||
.ascii "Hello world from child\n"
|
||||
message_child_end:
|
@ -2,20 +2,18 @@
|
||||
|
||||
.section .text
|
||||
_start:
|
||||
call print_message
|
||||
call print_message
|
||||
call print_message
|
||||
call print_message
|
||||
call print_message
|
||||
call print_message
|
||||
mov $60, %rax # syscall number of exit
|
||||
mov $0, %rdi # exit code
|
||||
mov $0, %rdi # exit code
|
||||
syscall
|
||||
print_message:
|
||||
mov $1, %rax # syscall number of write
|
||||
mov $1, %rdi # stdout
|
||||
mov $message, %rsi # address of message
|
||||
mov $message, %r11
|
||||
mov $message_end, %r12
|
||||
sub %r11, %r12 # calculate message len
|
||||
mov %r12, %rdx # number of bytes
|
||||
mov $message, %rsi # address of message
|
||||
mov $message_end, %rdx
|
||||
sub %rsi, %rdx # calculate message len
|
||||
syscall
|
||||
ret
|
||||
.section .rodata
|
||||
|
@ -20,8 +20,6 @@ fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
|
||||
|
||||
kxos_std::init();
|
||||
kxos_std::run_first_process();
|
||||
|
||||
loop {}
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
|
Loading…
x
Reference in New Issue
Block a user