11.3. 命令行——执行程序

本章代码对应 commit :ca94d49d69c18ce2925e3949d718cd74ddc3432c

用户程序

在 linux 中,ls, cd, pwd 等命令,其实都是可执行程序。这里我们创建一个简单的 hello 程序:

// in usr/rust/src/bin/hello.rs

#![no_std]
#![no_main]

#[macro_use]
extern crate rust;

#[no_mangle]
pub fn main() -> i32 {
    println!("Hello world!");
    return 0;
}

接下来,需要修改命令行,使得其能够通过系统调用创建并执行程序:

// in usr/rust/src/bin/shell.rs

#![no_std]
#![no_main]
#![feature(alloc)]

extern crate alloc;

#[macro_use]
extern crate rust;

use rust::io::getc;
use rust::syscall::sys_exec;
use alloc::string::String;

const LF: u8 = 0x0au8;
const CR: u8 = 0x0du8;

// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() -> i32 {
    println!("Rust user shell");
    let mut line: String = String::new();
    print!(">> ");
    loop {
        let c = getc();
        match c {
            LF | CR => {
                println!("");
                if !line.is_empty() {
                    sys_exec(line.as_ptr());
                    line.clear();
                }
                print!(">> ");
            }
            _ => {
                print!("{}", c as char);
                line.push(c as char)
            }
        }
    }
}

// in usr/rust/bin/shell.rs

pub fn sys_exec(path : *const u8) {
    sys_call(SyscallId::Exec, path as usize, 0, 0, 0);
}

enum SyscallId {
    ...
    Exec = 221,
}

用户程序将输入的字符串的指针作为参数传给 os ,os 需要将其转换回字符串,再进行处理:

执行程序的代码在 process::init 中其实已经有了哦,就是创建 shell 的部分:

这一章没有用到任何新知识呢,是不是学起来很快乐呢(反正我写起来挺快乐。。。(什))

一些 bug

发现了一些以前写的 bug :

  1. 在 alloc tid 的时候,通过 threads[id].is_none() 判断 id 是否被分配,但是程序 exit 的时候并没有将其还原为 None 。所以需要进行一些修改:

  2. rust/src/lang_items.rs 中,程序结束调用 sys_exit(0) ,返回值被写死了,应该改为:

Last updated

Was this helpful?