xv6はCで書かれたuniuxライクなミニマムOSです。
オリジナルechoはこちらのシンプルなコードです。

echo.c
#include "types.h"
#include "stat.h"
#include "user.h"

int
main(int argc, char *argv[])
{
  int i;

  for(i = 1; i < argc; i++)
    printf(1, "%s%s", argv[i], i+1 < argc ? " " : "\n");
  exit();
}

これをRustで書き換えます。
(ちょっと手を抜いてます)
@tatsuya6502さんが完璧なコードを書いてくれました。コメントをご覧ください。

echo.rs
#![no_std]
#![feature(lang_items)]
#![no_main]

extern{
    fn exit() -> i32;
    fn printf(fd: i32, fmt: *const u8, ...);
}

#[no_mangle]
pub extern fn main(main: *const u8, argc: isize, argv: *const *const u8) -> i32 {
    unsafe {
        printf(1, "%s\n".as_ptr(), argv.offset(-1));
        exit()
    }
}

#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop {} }

このプログラムはfreestandingなので、#[no_std]を指定します。
Cのexit(),printf()を呼びたいのでexternで指定します。
Cからも呼び出せるように#[no_main]と#[no_mangle]を指定して、pub externでmain関数を作成します。

MakefileにRustのコンパイルとリンクを追加します。

_echo: echo.rs
    rustc --target=i686-unknown-linux-gnu --emit=obj echo.rs
    ld -m    elf_i386 -N -e main -Ttext 0 -o _echo echo.o ulib.o usys.o printf.o umalloc.o

qemuで実行してみます。

$ echo a
a
(null)$

うまくいってそうですが変な(null)が差し込まれてしまいました。
これはprintf()の修正が必要そうですが、ここまでにします。
※こちらも@tatsuya6502さんが修正してくれました。コメントをご覧ください。

参考

Introduction Rust for Creating Your Operating System
標準ライブラリーの不使用

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.