mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
replace nasm assembly with gcc/clang assembly; add hello_world binary with git lfs
This commit is contained in:
parent
2e28cf5fcb
commit
8bebe380ba
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/kxos-user/hello_world/hello_world filter=lfs diff=lfs merge=lfs -text
|
@ -111,6 +111,7 @@ impl<'a> UserMode<'a> {
|
||||
self.user_space.vm_space().activate();
|
||||
if !self.executed {
|
||||
self.current.syscall_frame().caller.rcx = self.user_space.cpu_ctx.gp_regs.rip as usize;
|
||||
self.current.syscall_frame().callee.rsp = self.user_space.cpu_ctx.gp_regs.rsp as usize;
|
||||
self.executed = true;
|
||||
} else {
|
||||
if self.current.inner_exclusive_access().is_from_trap {
|
||||
@ -137,6 +138,7 @@ impl<'a> UserMode<'a> {
|
||||
} else {
|
||||
self.context = CpuContext::from(*self.current.syscall_frame());
|
||||
println!("[kernel] syscall id:{}",self.context.gp_regs.rax);
|
||||
println!("[kernel] rsp: 0x{:x}", self.context.gp_regs.rsp);
|
||||
UserEvent::Syscall
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use core::{ops::Range, cmp::Ordering};
|
||||
use core::{cmp::Ordering, ops::Range};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use kxos_frame::{
|
||||
vm::{Vaddr, VmAllocOptions, VmFrameVec, VmIo, VmPerm, VmSpace, VmMapOptions},
|
||||
Error, config::PAGE_SIZE,
|
||||
config::PAGE_SIZE,
|
||||
vm::{Vaddr, VmAllocOptions, VmFrameVec, VmIo, VmMapOptions, VmPerm, VmSpace},
|
||||
Error,
|
||||
};
|
||||
use xmas_elf::{
|
||||
header,
|
||||
@ -39,7 +40,7 @@ impl<'a> ElfSegment<'a> {
|
||||
Ok(type_) => type_,
|
||||
};
|
||||
let data = match read_segment_data(segment, elf_file) {
|
||||
Err(_) => return Err(ElfError::from("")),
|
||||
Err(msg) => return Err(ElfError::from(msg)),
|
||||
Ok(data) => data,
|
||||
};
|
||||
let vm_perm = Self::parse_segment_perm(segment)?;
|
||||
@ -188,8 +189,10 @@ impl<'a> ElfLoadInfo<'a> {
|
||||
for segment in self.segments.iter() {
|
||||
let start_address = segment.start_address();
|
||||
let len = segment.data.len();
|
||||
let mut read_buffer = vec![0;len];
|
||||
vm_space.read_bytes(start_address, &mut read_buffer).expect("read bytes failed");
|
||||
let mut read_buffer = vec![0; len];
|
||||
vm_space
|
||||
.read_bytes(start_address, &mut read_buffer)
|
||||
.expect("read bytes failed");
|
||||
let res = segment.data.cmp(&read_buffer);
|
||||
assert_eq!(res, Ordering::Equal);
|
||||
}
|
||||
@ -255,14 +258,17 @@ impl From<Error> for ElfError {
|
||||
fn read_segment_data<'a>(
|
||||
segment: ProgramHeader<'a>,
|
||||
elf_file: &ElfFile<'a>,
|
||||
) -> Result<&'a [u8], ()> {
|
||||
) -> Result<&'a [u8], &'static str> {
|
||||
match segment.get_data(&elf_file) {
|
||||
Err(_) => Err(()),
|
||||
Err(msg) => Err(msg),
|
||||
Ok(data) => {
|
||||
if let SegmentData::Undefined(data) = data {
|
||||
match data {
|
||||
SegmentData::Note64(_, data) | SegmentData::Undefined(data) => {
|
||||
Ok(data)
|
||||
} else {
|
||||
Err(())
|
||||
},
|
||||
_ => {
|
||||
Err("Unkonwn segment data type")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod elf;
|
||||
pub mod user_stack;
|
||||
pub mod vm_page;
|
||||
use kxos_frame::{vm::VmSpace, debug};
|
||||
use kxos_frame::{debug, vm::VmSpace};
|
||||
|
||||
use self::elf::{ElfError, ElfLoadInfo};
|
||||
|
||||
|
@ -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::{task::Task, debug};
|
||||
use kxos_frame::{debug, task::Task};
|
||||
|
||||
use self::task::spawn_user_task_from_elf;
|
||||
|
||||
@ -34,12 +34,19 @@ impl Process {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_kernel_task<F>(task_fn: F) -> Self where F: Fn() + Send + Sync + 'static {
|
||||
pub fn spawn_kernel_task<F>(task_fn: F) -> Self
|
||||
where
|
||||
F: Fn() + Send + Sync + 'static,
|
||||
{
|
||||
let pid = new_pid();
|
||||
debug!("pid = {}" , pid);
|
||||
debug!("pid = {}", pid);
|
||||
let task = Task::spawn(task_fn, None::<u8>, None).expect("spawn kernel task failed");
|
||||
let exit_code = 0;
|
||||
Self { pid, task, exit_code }
|
||||
Self {
|
||||
pid,
|
||||
task,
|
||||
exit_code,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
use alloc::sync::Arc;
|
||||
use kxos_frame::{
|
||||
cpu::CpuContext,
|
||||
println,
|
||||
task::Task,
|
||||
user::{UserEvent, UserMode, UserSpace},
|
||||
vm::VmSpace,
|
||||
vm::VmSpace, debug,
|
||||
};
|
||||
|
||||
use crate::{memory::load_elf_to_vm_space, syscall::syscall_handler};
|
||||
@ -27,6 +26,7 @@ pub fn spawn_user_task_from_elf(elf_file_content: &[u8]) -> Arc<Task> {
|
||||
let mut user_mode = UserMode::new(user_space);
|
||||
loop {
|
||||
let user_event = user_mode.execute();
|
||||
debug!("return from user mode");
|
||||
let context = user_mode.context_mut();
|
||||
if let HandlerResult::Exit = handle_user_event(user_event, context) {
|
||||
// FIXME: How to set task status? How to set exit code of process?
|
||||
|
@ -1,4 +1,3 @@
|
||||
use alloc::ffi::CString;
|
||||
use alloc::vec;
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use kxos_frame::cpu::CpuContext;
|
||||
@ -12,7 +11,7 @@ use crate::process::task::HandlerResult;
|
||||
const SYS_WRITE: u64 = 1;
|
||||
const SYS_EXIT: u64 = 60;
|
||||
|
||||
pub struct SyscallFrame {
|
||||
pub struct SyscallArgument {
|
||||
syscall_number: u64,
|
||||
args: [u64; 6],
|
||||
}
|
||||
@ -22,7 +21,7 @@ pub enum SyscallResult {
|
||||
Return(i32),
|
||||
}
|
||||
|
||||
impl SyscallFrame {
|
||||
impl SyscallArgument {
|
||||
fn new_from_context(context: &CpuContext) -> Self {
|
||||
let syscall_number = context.gp_regs.rax;
|
||||
let mut args = [0u64; 6];
|
||||
@ -40,7 +39,7 @@ impl SyscallFrame {
|
||||
}
|
||||
|
||||
pub fn syscall_handler(context: &mut CpuContext) -> HandlerResult {
|
||||
let syscall_frame = SyscallFrame::new_from_context(context);
|
||||
let syscall_frame = SyscallArgument::new_from_context(context);
|
||||
let syscall_return = syscall_dispatch(syscall_frame.syscall_number, syscall_frame.args);
|
||||
|
||||
match syscall_return {
|
||||
|
@ -1,8 +1,6 @@
|
||||
.PHONY: build clean run
|
||||
build: hello_world.s
|
||||
@nasm -f elf64 hello_world.s -o hello_world.o
|
||||
@ld hello_world.o -o hello_world
|
||||
@rm hello_world.o
|
||||
@gcc -static -nostdlib hello_world.s -o hello_world
|
||||
clean:
|
||||
@rm hello_world
|
||||
run: build
|
||||
|
3
src/kxos-user/hello_world/hello_world
Executable file
3
src/kxos-user/hello_world/hello_world
Executable file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0ac54a2485e87769b102225e0a2d7c25e449a01bd0b2504a164fe1ce205acb13
|
||||
size 9072
|
@ -1,18 +1,24 @@
|
||||
global _start
|
||||
|
||||
section .text
|
||||
.global _start
|
||||
|
||||
.section .text
|
||||
_start:
|
||||
mov rax, 1 ; syswrite
|
||||
mov rdi, 1 ; fd
|
||||
mov rsi, msg ; "Hello, world!\n",
|
||||
mov rdx, msglen ; sizeof("Hello, world!\n")
|
||||
call print_message
|
||||
call print_message
|
||||
call print_message
|
||||
mov $60, %rax # syscall number of exit
|
||||
mov $0, %rdi # exit code
|
||||
syscall
|
||||
|
||||
mov rax, 60 ; sys_exit
|
||||
mov rdi, 0 ; exit_code
|
||||
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
|
||||
syscall
|
||||
|
||||
section .rodata
|
||||
msg: db "Hello, world!", 10
|
||||
msglen: equ $ - msg
|
||||
ret
|
||||
.section .rodata
|
||||
message:
|
||||
.ascii "Hello, world\n"
|
||||
message_end:
|
||||
|
Loading…
x
Reference in New Issue
Block a user