port c init to rust
This commit is contained in:
parent
1b618c7caf
commit
562f549935
|
@ -1,3 +1,4 @@
|
||||||
out/*
|
out/*
|
||||||
cache/*
|
cache/*
|
||||||
.*
|
.*
|
||||||
|
src/init/target
|
||||||
|
|
31
Makefile
31
Makefile
|
@ -218,6 +218,7 @@ define toolchain
|
||||||
--env KBUILD_BUILD_TIMESTAMP=$(KBUILD_BUILD_TIMESTAMP) \
|
--env KBUILD_BUILD_TIMESTAMP=$(KBUILD_BUILD_TIMESTAMP) \
|
||||||
--env KCONFIG_NOTIMESTAMP=$(KCONFIG_NOTIMESTAMP) \
|
--env KCONFIG_NOTIMESTAMP=$(KCONFIG_NOTIMESTAMP) \
|
||||||
--env SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) \
|
--env SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) \
|
||||||
|
--env CARGO_HOME=/cache/cargo \
|
||||||
local/$(NAME)-build \
|
local/$(NAME)-build \
|
||||||
bash -c $(2)
|
bash -c $(2)
|
||||||
endef
|
endef
|
||||||
|
@ -250,12 +251,12 @@ $(OUT_DIR)/busybox: \
|
||||||
|
|
||||||
$(OUT_DIR)/init:
|
$(OUT_DIR)/init:
|
||||||
$(call toolchain,$(USER)," \
|
$(call toolchain,$(USER)," \
|
||||||
gcc \
|
cd /src/init/ && \
|
||||||
-static \
|
RUSTFLAGS='-C target-feature=+crt-static' cargo build --release && \
|
||||||
-static-libgcc /src/init/init.c \
|
cp /src/init/target/release/init /out/init \
|
||||||
-o /out/init; \
|
|
||||||
")
|
")
|
||||||
|
|
||||||
|
|
||||||
$(CACHE_DIR)/linux-$(LINUX_VERSION)/usr/gen_init_cpio: \
|
$(CACHE_DIR)/linux-$(LINUX_VERSION)/usr/gen_init_cpio: \
|
||||||
$(CACHE_DIR)/linux-$(LINUX_VERSION) \
|
$(CACHE_DIR)/linux-$(LINUX_VERSION) \
|
||||||
$(CACHE_DIR)/linux-$(LINUX_VERSION) \
|
$(CACHE_DIR)/linux-$(LINUX_VERSION) \
|
||||||
|
@ -269,21 +270,17 @@ $(CACHE_DIR)/linux-$(LINUX_VERSION)/usr/gen_init_cpio: \
|
||||||
$(OUT_DIR)/$(TARGET)/rootfs.cpio: \
|
$(OUT_DIR)/$(TARGET)/rootfs.cpio: \
|
||||||
$(OUT_DIR)/busybox \
|
$(OUT_DIR)/busybox \
|
||||||
$(OUT_DIR)/init \
|
$(OUT_DIR)/init \
|
||||||
|
$(OUT_DIR)/aws/nsm.ko \
|
||||||
$(CACHE_DIR)/linux-$(LINUX_VERSION)/usr/gen_init_cpio
|
$(CACHE_DIR)/linux-$(LINUX_VERSION)/usr/gen_init_cpio
|
||||||
mkdir -p $(CACHE_DIR)/$(TARGET)/rootfs/bin
|
cp $(CONFIG_DIR)/$(TARGET)/rootfs.list $(CACHE_DIR)/$(TARGET)/rootfs.list
|
||||||
cp $(CONFIG_DIR)/generic/rootfs.list $(CACHE_DIR)/$(TARGET)/rootfs.list
|
cp $(OUT_DIR)/init $(CACHE_DIR)/$(TARGET)/rootfs/init
|
||||||
ifeq ($(DEBUG), true)
|
ifeq ($(DEBUG), true)
|
||||||
cp $(OUT_DIR)/init $(CACHE_DIR)/$(TARGET)/rootfs/real_init
|
mv $(CACHE_DIR)/$(TARGET)/rootfs/init $(CACHE_DIR)/$(TARGET)/rootfs/real_init
|
||||||
cp $(SRC_DIR)/scripts/busybox_init $(CACHE_DIR)/$(TARGET)/rootfs/init
|
cp $(SRC_DIR)/scripts/busybox_init $(CACHE_DIR)/$(TARGET)/rootfs/init
|
||||||
|
mkdir -p $(CACHE_DIR)/$(TARGET)/rootfs/bin
|
||||||
cp $(OUT_DIR)/busybox $(CACHE_DIR)/$(TARGET)/rootfs/bin/
|
cp $(OUT_DIR)/busybox $(CACHE_DIR)/$(TARGET)/rootfs/bin/
|
||||||
echo "file /bin/busybox /cache/rootfs/bin/busybox 0755 0 0" \
|
echo "file /bin/busybox /cache/rootfs/bin/busybox 0755 0 0" \
|
||||||
>> $(CACHE_DIR)/$(TARGET)/rootfs.list
|
>> $(CACHE_DIR)/$(TARGET)/rootfs.list
|
||||||
else
|
|
||||||
cp $(OUT_DIR)/init $(CACHE_DIR)/$(TARGET)/rootfs/init
|
|
||||||
endif
|
|
||||||
ifeq ($(TARGET), aws)
|
|
||||||
echo "file /nsm.ko /out/aws/nsm.ko 0755 0 0" \
|
|
||||||
>> $(CACHE_DIR)/$(TARGET)/rootfs.list
|
|
||||||
endif
|
endif
|
||||||
$(call toolchain,$(USER)," \
|
$(call toolchain,$(USER)," \
|
||||||
cd /cache/$(TARGET)/rootfs && \
|
cd /cache/$(TARGET)/rootfs && \
|
||||||
|
@ -294,11 +291,11 @@ endif
|
||||||
-o /out/$(TARGET)/rootfs.cpio \
|
-o /out/$(TARGET)/rootfs.cpio \
|
||||||
/cache/$(TARGET)/rootfs.list && \
|
/cache/$(TARGET)/rootfs.list && \
|
||||||
cpio -itv < /out/$(TARGET)/rootfs.cpio && \
|
cpio -itv < /out/$(TARGET)/rootfs.cpio && \
|
||||||
sha256sum /out/rootfs.cpio; \
|
sha256sum /out/$(TARGET)/rootfs.cpio; \
|
||||||
")
|
")
|
||||||
|
|
||||||
$(OUT_DIR)/$(TARGET)/bzImage: \
|
$(OUT_DIR)/$(TARGET)/bzImage: \
|
||||||
$(OUT_DIR)/rootfs.cpio
|
$(OUT_DIR)/$(TARGET)/rootfs.cpio
|
||||||
$(call toolchain,$(USER)," \
|
$(call toolchain,$(USER)," \
|
||||||
cd /cache/linux-$(LINUX_VERSION) && \
|
cd /cache/linux-$(LINUX_VERSION) && \
|
||||||
cp /config/$(TARGET)/linux.config .config && \
|
cp /config/$(TARGET)/linux.config .config && \
|
||||||
|
@ -332,14 +329,14 @@ endif
|
||||||
$(OUT_DIR)/aws/nitro.eif: \
|
$(OUT_DIR)/aws/nitro.eif: \
|
||||||
$(OUT_DIR)/aws/eif_build \
|
$(OUT_DIR)/aws/eif_build \
|
||||||
$(OUT_DIR)/$(TARGET)/bzImage \
|
$(OUT_DIR)/$(TARGET)/bzImage \
|
||||||
$(OUT_DIR)/rootfs.cpio
|
$(OUT_DIR)/$(TARGET)/rootfs.cpio
|
||||||
ifeq ($(TARGET), aws)
|
ifeq ($(TARGET), aws)
|
||||||
$(call toolchain,$(USER)," \
|
$(call toolchain,$(USER)," \
|
||||||
/out/eif_build \
|
/out/eif_build \
|
||||||
--kernel /out/$(TARGET)/bzImage \
|
--kernel /out/$(TARGET)/bzImage \
|
||||||
--kernel_config /config/$(TARGET)/linux.config \
|
--kernel_config /config/$(TARGET)/linux.config \
|
||||||
--cmdline 'reboot=k initrd=0x2000000$(,)3228672 root=/dev/ram0 panic=1 pci=off nomodules console=ttyS0 i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd' \
|
--cmdline 'reboot=k initrd=0x2000000$(,)3228672 root=/dev/ram0 panic=1 pci=off nomodules console=ttyS0 i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd' \
|
||||||
--ramdisk /out/rootfs.cpio \
|
--ramdisk /out/aws/rootfs.cpio \
|
||||||
--output /out/aws/nitro.eif; \
|
--output /out/aws/nitro.eif; \
|
||||||
")
|
")
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
dir /dev 0755 0 0
|
||||||
|
nod /dev/console 0600 0 0 c 5 1
|
||||||
|
dir /sys 0755 0 0
|
||||||
|
dir /usr 0755 0 0
|
||||||
|
dir /etc 0755 0 0
|
||||||
|
dir /proc 0755 0 0
|
||||||
|
dir /bin 0755 0 0
|
||||||
|
dir /sbin 0755 0 0
|
||||||
|
dir /usr/bin 0755 0 0
|
||||||
|
dir /usr/sbin 0755 0 0
|
||||||
|
file /init /cache/aws/rootfs/init 0755 0 0
|
||||||
|
file /nsm.ko /out/aws/nsm.ko 0755 0 0
|
|
@ -0,0 +1,16 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "init"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.134"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "init"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2.134"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "init"
|
||||||
|
path = "init.rs"
|
189
src/init/init.c
189
src/init/init.c
|
@ -1,189 +0,0 @@
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <sys/reboot.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <sys/sysmacros.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <linux/vm_sockets.h>
|
|
||||||
#include <poll.h>
|
|
||||||
|
|
||||||
_Noreturn void die(const char *msg);
|
|
||||||
#define die_on(CONDITION, ...) \
|
|
||||||
do { \
|
|
||||||
if (CONDITION) { \
|
|
||||||
die(__VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define finit_module(fd, param_values, flags) (int)syscall(__NR_finit_module, fd, param_values, flags)
|
|
||||||
#define DEFAULT_PATH_ENV "PATH=/sbin:/usr/sbin:/bin:/usr/bin"
|
|
||||||
#define NSM_PATH "nsm.ko"
|
|
||||||
#define TIMEOUT 20000
|
|
||||||
#define VSOCK_PORT 9000
|
|
||||||
#define VSOCK_CID 3
|
|
||||||
#define HEART_BEAT 0xB7
|
|
||||||
|
|
||||||
const char *const default_envp[] = {
|
|
||||||
DEFAULT_PATH_ENV,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *const default_argv[] = { "sh", NULL };
|
|
||||||
|
|
||||||
struct Mount {
|
|
||||||
const char *source, *target, *type;
|
|
||||||
unsigned long flags;
|
|
||||||
const void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Mkdir {
|
|
||||||
const char *path;
|
|
||||||
mode_t mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Mknod {
|
|
||||||
const char *path;
|
|
||||||
mode_t mode;
|
|
||||||
int major, minor;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Symlink {
|
|
||||||
const char *linkpath, *target;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum OpType {
|
|
||||||
OpMount,
|
|
||||||
OpMkdir,
|
|
||||||
OpMknod,
|
|
||||||
OpSymlink,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InitOp {
|
|
||||||
enum OpType op;
|
|
||||||
union {
|
|
||||||
struct Mount mount;
|
|
||||||
struct Mkdir mkdir;
|
|
||||||
struct Mknod mknod;
|
|
||||||
struct Symlink symlink;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct InitOp ops[] = {
|
|
||||||
{ OpMount, .mount = { "proc", "/proc", "proc", MS_NODEV | MS_NOSUID | MS_NOEXEC } },
|
|
||||||
{ OpSymlink, .symlink = { "/dev/fd", "/proc/self/fd" } },
|
|
||||||
{ OpSymlink, .symlink = { "/dev/stdin", "/proc/self/fd/0" } },
|
|
||||||
{ OpSymlink, .symlink = { "/dev/stdout", "/proc/self/fd/1" } },
|
|
||||||
{ OpSymlink, .symlink = { "/dev/stderr", "/proc/self/fd/2" } },
|
|
||||||
{ OpMkdir, .mkdir = { "/dev/shm", 0755 } },
|
|
||||||
{ OpMkdir, .mkdir = { "/dev/pts", 0755 } },
|
|
||||||
{ OpMount, .mount = { "devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC } },
|
|
||||||
{ OpMount, .mount = { "sysfs", "/sys", "sysfs", MS_NODEV | MS_NOSUID | MS_NOEXEC } },
|
|
||||||
};
|
|
||||||
|
|
||||||
void warn(const char *msg) {
|
|
||||||
int error = errno;
|
|
||||||
perror(msg);
|
|
||||||
errno = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void warn2(const char *msg1, const char *msg2) {
|
|
||||||
int error = errno;
|
|
||||||
fputs(msg1, stderr);
|
|
||||||
fputs(": ", stderr);
|
|
||||||
errno = error;
|
|
||||||
warn(msg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
_Noreturn void dien() {
|
|
||||||
exit(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
_Noreturn void die(const char *msg) {
|
|
||||||
warn(msg);
|
|
||||||
dien();
|
|
||||||
}
|
|
||||||
|
|
||||||
_Noreturn void die2(const char *msg1, const char *msg2) {
|
|
||||||
warn2(msg1, msg2);
|
|
||||||
dien();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_dev() {
|
|
||||||
if (mount("dev", "/dev", "devtmpfs", MS_NOSUID | MS_NOEXEC, NULL) < 0) {
|
|
||||||
warn2("mount", "/dev");
|
|
||||||
if (errno != EBUSY) {
|
|
||||||
dien();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_console() {
|
|
||||||
const char *console_path = "/dev/console";
|
|
||||||
die_on(freopen(console_path, "r", stdin) == NULL,
|
|
||||||
"freopen failed for stdin");
|
|
||||||
die_on(freopen(console_path, "w", stdout) == NULL,
|
|
||||||
"freopen failed for stdout");
|
|
||||||
die_on(freopen(console_path, "w", stderr) == NULL,
|
|
||||||
"freopen failed for stderr");
|
|
||||||
}
|
|
||||||
|
|
||||||
void enclave_ready() {
|
|
||||||
int socket_fd;
|
|
||||||
struct sockaddr_vm sa = {
|
|
||||||
.svm_family = AF_VSOCK,
|
|
||||||
.svm_cid = VSOCK_CID,
|
|
||||||
.svm_port = VSOCK_PORT,
|
|
||||||
.svm_reserved1 = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t buf[1];
|
|
||||||
buf[0] = HEART_BEAT;
|
|
||||||
errno = -EINVAL;
|
|
||||||
|
|
||||||
socket_fd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
|
||||||
die_on(socket_fd < 0, "socket");
|
|
||||||
die_on(connect(socket_fd, (struct sockaddr*) &sa, sizeof(sa)), "connect");
|
|
||||||
die_on(write(socket_fd, buf, 1) != 1, "write heartbeat");
|
|
||||||
die_on(read(socket_fd, buf, 1) != 1, "read heartbeat");
|
|
||||||
die_on(buf[0] != HEART_BEAT, "received wrong heartbeat");
|
|
||||||
die_on(close(socket_fd), "close");
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_nsm_driver() {
|
|
||||||
int fd;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
fd = open(NSM_PATH, O_RDONLY | O_CLOEXEC);
|
|
||||||
if (fd < 0 && errno == ENOENT) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
die_on(fd < 0, "failed to open nsm fd");
|
|
||||||
rc = finit_module(fd, "", 0);
|
|
||||||
die_on(rc < 0, "failed to insert nsm driver");
|
|
||||||
|
|
||||||
die_on(close(fd), "close nsm fd");
|
|
||||||
rc = unlink(NSM_PATH);
|
|
||||||
if (rc < 0)
|
|
||||||
warn("Could not unlink " NSM_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
init_dev();
|
|
||||||
init_console();
|
|
||||||
init_nsm_driver();
|
|
||||||
enclave_ready();
|
|
||||||
puts("\nHello World with NSM!\n");
|
|
||||||
reboot(RB_AUTOBOOT);
|
|
||||||
}
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
extern crate libc;
|
||||||
|
use libc::mount;
|
||||||
|
use libc::read;
|
||||||
|
use libc::write;
|
||||||
|
use libc::close;
|
||||||
|
use libc::reboot;
|
||||||
|
use libc::socket;
|
||||||
|
use libc::connect;
|
||||||
|
use libc::freopen;
|
||||||
|
use libc::fdopen;
|
||||||
|
use libc::c_void;
|
||||||
|
use libc::sockaddr;
|
||||||
|
use libc::sockaddr_vm;
|
||||||
|
use libc::SOCK_STREAM;
|
||||||
|
use libc::AF_VSOCK;
|
||||||
|
use libc::MS_NOSUID;
|
||||||
|
use libc::MS_NOEXEC;
|
||||||
|
use libc::RB_AUTOBOOT;
|
||||||
|
use std::mem::zeroed;
|
||||||
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
mount(
|
||||||
|
b"devtmpfs\0".as_ptr() as _,
|
||||||
|
b"/dev\0".as_ptr() as _,
|
||||||
|
b"devtmpfs\0".as_ptr() as _,
|
||||||
|
MS_NOSUID | MS_NOEXEC,
|
||||||
|
b"mode=0755\0".as_ptr() as *const c_void,
|
||||||
|
);
|
||||||
|
freopen(
|
||||||
|
b"/dev/console\0".as_ptr() as _,
|
||||||
|
b"r\0".as_ptr() as _,
|
||||||
|
fdopen(0, b"r\0".as_ptr() as *const i8)
|
||||||
|
);
|
||||||
|
freopen(
|
||||||
|
b"/dev/console\0".as_ptr() as _,
|
||||||
|
b"w\0".as_ptr() as _,
|
||||||
|
fdopen(1, b"w\0".as_ptr() as *const i8)
|
||||||
|
);
|
||||||
|
freopen(
|
||||||
|
b"/dev/console\0".as_ptr() as _,
|
||||||
|
b"w\0".as_ptr() as _,
|
||||||
|
|
||||||
|
fdopen(2, b"w\0".as_ptr() as *const i8)
|
||||||
|
);
|
||||||
|
let mut sa: sockaddr_vm = zeroed();
|
||||||
|
sa.svm_family = AF_VSOCK as _;
|
||||||
|
sa.svm_port = 9000;
|
||||||
|
sa.svm_cid = 3;
|
||||||
|
let fd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||||
|
connect(
|
||||||
|
fd,
|
||||||
|
&sa as *const _ as *mut sockaddr,
|
||||||
|
size_of::<sockaddr_vm>() as _,
|
||||||
|
);
|
||||||
|
let mut buf: [u8; 1] = [0; 1];
|
||||||
|
buf[0] = 0xB7;
|
||||||
|
write(fd, buf.as_ptr() as _, 1);
|
||||||
|
read(fd, buf.as_ptr() as _, 1);
|
||||||
|
close(fd);
|
||||||
|
println!("Hello World from Rust init!");
|
||||||
|
reboot(RB_AUTOBOOT);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue