From: Tulio A M Mendes Date: Sat, 7 Feb 2026 23:56:43 +0000 (-0300) Subject: kernel: add overlayfs root (initrd+tmpfs) for writable / X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=890a9f44a77216ef0dba96fc22a0f4263846d579;p=AdrOS.git kernel: add overlayfs root (initrd+tmpfs) for writable / --- diff --git a/include/overlayfs.h b/include/overlayfs.h new file mode 100644 index 0000000..19e976e --- /dev/null +++ b/include/overlayfs.h @@ -0,0 +1,8 @@ +#ifndef OVERLAYFS_H +#define OVERLAYFS_H + +#include "fs.h" + +fs_node_t* overlayfs_create_root(fs_node_t* lower_root, fs_node_t* upper_root); + +#endif diff --git a/include/tmpfs.h b/include/tmpfs.h index 8a57ec2..cc56087 100644 --- a/include/tmpfs.h +++ b/include/tmpfs.h @@ -7,4 +7,7 @@ fs_node_t* tmpfs_create_root(void); int tmpfs_add_file(fs_node_t* root_dir, const char* name, const uint8_t* data, uint32_t len); +int tmpfs_mkdir_p(fs_node_t* root_dir, const char* path); +fs_node_t* tmpfs_create_file(fs_node_t* root_dir, const char* path, const uint8_t* data, uint32_t len); + #endif diff --git a/src/arch/x86/vmm.c b/src/arch/x86/vmm.c index f3aa87e..e671b0b 100644 --- a/src/arch/x86/vmm.c +++ b/src/arch/x86/vmm.c @@ -100,6 +100,9 @@ uintptr_t vmm_as_create_kernel_clone(void) { pd_virt[i] = boot_pd[i]; } + // Fix recursive mapping: PDE[1023] must point to this PD, not boot_pd. + pd_virt[1023] = pd_phys | X86_PTE_PRESENT | X86_PTE_RW; + return (uintptr_t)pd_phys; } diff --git a/src/kernel/fs.c b/src/kernel/fs.c index 7c162b1..de72c38 100644 --- a/src/kernel/fs.c +++ b/src/kernel/fs.c @@ -93,12 +93,6 @@ void vfs_close(fs_node_t* node) { fs_node_t* vfs_lookup(const char* path) { if (!path || !fs_root) return NULL; - if (strcmp(path, "/") == 0) return fs_root; - - const char* start_path = path; - while (*start_path == '/') start_path++; - if (*start_path == 0) return fs_root; - fs_node_t* base = fs_root; const char* rel = path; size_t best_len = 0; @@ -117,6 +111,7 @@ fs_node_t* vfs_lookup(const char* path) { } } + if (!rel) return NULL; while (*rel == '/') rel++; if (*rel == 0) return base; diff --git a/src/kernel/init.c b/src/kernel/init.c index 8b96d85..c0361ac 100644 --- a/src/kernel/init.c +++ b/src/kernel/init.c @@ -4,6 +4,7 @@ #include "fs.h" #include "initrd.h" +#include "overlayfs.h" #include "tmpfs.h" #include "tty.h" #include "uart_console.h" @@ -43,6 +44,16 @@ int init_start(const struct boot_info* bi) { } } + if (fs_root) { + fs_node_t* upper = tmpfs_create_root(); + if (upper) { + fs_node_t* ovl = overlayfs_create_root(fs_root, upper); + if (ovl) { + (void)vfs_mount("/", ovl); + } + } + } + fs_node_t* tmp = tmpfs_create_root(); if (tmp) { static const uint8_t hello[] = "hello from tmpfs\n"; diff --git a/src/kernel/overlayfs.c b/src/kernel/overlayfs.c new file mode 100644 index 0000000..3fa32e5 --- /dev/null +++ b/src/kernel/overlayfs.c @@ -0,0 +1,197 @@ +#include "overlayfs.h" + +#include "heap.h" +#include "utils.h" +#include "tmpfs.h" + +#include + +struct overlayfs { + fs_node_t* lower; + fs_node_t* upper; +}; + +struct overlay_node { + fs_node_t vfs; + struct overlayfs* ofs; + + fs_node_t* lower; + fs_node_t* upper; + + char path[256]; +}; + +static struct fs_node* overlay_finddir_impl(struct fs_node* node, char* name); + +static void overlay_str_copy_n(char* dst, size_t dst_sz, const char* src, size_t src_n) { + if (!dst || dst_sz == 0) return; + size_t i = 0; + for (; i + 1 < dst_sz && i < src_n; i++) { + char c = src[i]; + if (c == 0) break; + dst[i] = c; + } + dst[i] = 0; +} + +static uint32_t overlay_read_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) { + if (!node) return 0; + struct overlay_node* on = (struct overlay_node*)node; + + fs_node_t* src = on->upper ? on->upper : on->lower; + if (!src) return 0; + return vfs_read(src, offset, size, buffer); +} + +static fs_node_t* overlay_copy_up_file(struct overlay_node* on) { + if (!on || on->upper) return on ? on->upper : NULL; + if (!on->ofs || !on->ofs->upper) return NULL; + if (!on->lower) return NULL; + if (on->vfs.flags != FS_FILE) return NULL; + + uint32_t len = on->lower->length; + uint8_t* buf = NULL; + if (len) { + buf = (uint8_t*)kmalloc(len); + if (!buf) return NULL; + uint32_t rd = vfs_read(on->lower, 0, len, buf); + if (rd != len) { + if (buf) kfree(buf); + return NULL; + } + } + + fs_node_t* created = tmpfs_create_file(on->ofs->upper, on->path, buf, len); + if (buf) kfree(buf); + if (!created) return NULL; + + on->upper = created; + on->vfs.length = created->length; + on->vfs.inode = created->inode; + return created; +} + +static uint32_t overlay_write_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) { + if (!node) return 0; + struct overlay_node* on = (struct overlay_node*)node; + + fs_node_t* dst = on->upper; + if (!dst) { + dst = overlay_copy_up_file(on); + } + if (!dst) return 0; + + uint32_t wr = vfs_write(dst, offset, size, buffer); + if (dst->length > on->vfs.length) on->vfs.length = dst->length; + return wr; +} + +static fs_node_t* overlay_wrap_child(struct overlay_node* parent, const char* name, fs_node_t* lower_child, fs_node_t* upper_child) { + if (!parent || !parent->ofs || !name) return NULL; + if (!lower_child && !upper_child) return NULL; + + struct overlay_node* c = (struct overlay_node*)kmalloc(sizeof(*c)); + if (!c) return NULL; + memset(c, 0, sizeof(*c)); + + strcpy(c->vfs.name, name); + c->ofs = parent->ofs; + c->lower = lower_child; + c->upper = upper_child; + + if (upper_child) { + c->vfs.flags = upper_child->flags; + c->vfs.inode = upper_child->inode; + c->vfs.length = upper_child->length; + } else { + c->vfs.flags = lower_child->flags; + c->vfs.inode = lower_child->inode; + c->vfs.length = lower_child->length; + } + + c->vfs.read = &overlay_read_impl; + c->vfs.write = (c->vfs.flags == FS_FILE) ? &overlay_write_impl : 0; + c->vfs.open = 0; + c->vfs.close = 0; + c->vfs.finddir = (c->vfs.flags == FS_DIRECTORY) ? &overlay_finddir_impl : 0; + + if (parent->path[0] == 0) { + c->path[0] = '/'; + c->path[1] = 0; + } else { + strcpy(c->path, parent->path); + } + + size_t l = strlen(c->path); + if (l == 0) { + c->path[0] = '/'; + c->path[1] = 0; + l = 1; + } + if (l + 1 < sizeof(c->path) && c->path[l - 1] != '/') { + c->path[l++] = '/'; + c->path[l] = 0; + } + + size_t cur = strlen(c->path); + if (cur + 1 < sizeof(c->path)) { + size_t rem = sizeof(c->path) - cur - 1; + overlay_str_copy_n(c->path + cur, rem + 1, name, strlen(name)); + } + + return &c->vfs; +} + +static struct fs_node* overlay_finddir_impl(struct fs_node* node, char* name) { + if (!node || !name) return 0; + if (node->flags != FS_DIRECTORY) return 0; + + struct overlay_node* dir = (struct overlay_node*)node; + + fs_node_t* upper_child = NULL; + fs_node_t* lower_child = NULL; + + if (dir->upper && dir->upper->finddir) { + upper_child = dir->upper->finddir(dir->upper, name); + } + if (dir->lower && dir->lower->finddir) { + lower_child = dir->lower->finddir(dir->lower, name); + } + + if (!upper_child && !lower_child) return 0; + return overlay_wrap_child(dir, name, lower_child, upper_child); +} + +fs_node_t* overlayfs_create_root(fs_node_t* lower_root, fs_node_t* upper_root) { + if (!lower_root || !upper_root) return NULL; + + struct overlayfs* ofs = (struct overlayfs*)kmalloc(sizeof(*ofs)); + if (!ofs) return NULL; + ofs->lower = lower_root; + ofs->upper = upper_root; + + struct overlay_node* root = (struct overlay_node*)kmalloc(sizeof(*root)); + if (!root) { + kfree(ofs); + return NULL; + } + memset(root, 0, sizeof(*root)); + + root->ofs = ofs; + root->lower = lower_root; + root->upper = upper_root; + + root->vfs.name[0] = 0; + root->vfs.flags = FS_DIRECTORY; + root->vfs.inode = upper_root->inode; + root->vfs.length = 0; + root->vfs.read = 0; + root->vfs.write = 0; + root->vfs.open = 0; + root->vfs.close = 0; + root->vfs.finddir = &overlay_finddir_impl; + + root->path[0] = 0; + + return &root->vfs; +} diff --git a/src/kernel/tmpfs.c b/src/kernel/tmpfs.c index c1219fb..f3efc33 100644 --- a/src/kernel/tmpfs.c +++ b/src/kernel/tmpfs.c @@ -15,6 +15,9 @@ struct tmpfs_node { static uint32_t g_tmpfs_next_inode = 1; +static struct fs_node* tmpfs_finddir_impl(struct fs_node* node, char* name); +static uint32_t tmpfs_write_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer); + static struct tmpfs_node* tmpfs_node_alloc(const char* name, uint32_t flags) { struct tmpfs_node* n = (struct tmpfs_node*)kmalloc(sizeof(*n)); if (!n) return NULL; @@ -49,6 +52,48 @@ static void tmpfs_child_add(struct tmpfs_node* dir, struct tmpfs_node* child) { dir->first_child = child; } +static struct tmpfs_node* tmpfs_child_ensure_dir(struct tmpfs_node* dir, const char* name) { + if (!dir || !name || name[0] == 0) return NULL; + struct tmpfs_node* existing = tmpfs_child_find(dir, name); + if (existing) { + if (existing->vfs.flags != FS_DIRECTORY) return NULL; + return existing; + } + + struct tmpfs_node* nd = tmpfs_node_alloc(name, FS_DIRECTORY); + if (!nd) return NULL; + nd->vfs.read = 0; + nd->vfs.write = 0; + nd->vfs.open = 0; + nd->vfs.close = 0; + nd->vfs.finddir = &tmpfs_finddir_impl; + tmpfs_child_add(dir, nd); + return nd; +} + +static int tmpfs_split_next(const char** p_inout, char* out, size_t out_sz) { + if (!p_inout || !*p_inout || !out || out_sz == 0) return 0; + const char* p = *p_inout; + while (*p == '/') p++; + if (*p == 0) { + *p_inout = p; + out[0] = 0; + return 0; + } + + size_t i = 0; + while (*p != 0 && *p != '/') { + if (i + 1 < out_sz) { + out[i++] = *p; + } + p++; + } + out[i] = 0; + while (*p == '/') p++; + *p_inout = p; + return out[0] != 0; +} + static uint32_t tmpfs_read_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) { if (!node || !buffer) return 0; if (node->flags != FS_FILE) return 0; @@ -145,3 +190,79 @@ int tmpfs_add_file(fs_node_t* root_dir, const char* name, const uint8_t* data, u tmpfs_child_add(dir, f); return 0; } + +int tmpfs_mkdir_p(fs_node_t* root_dir, const char* path) { + if (!root_dir || root_dir->flags != FS_DIRECTORY) return -1; + if (!path) return -1; + + struct tmpfs_node* cur = (struct tmpfs_node*)root_dir; + const char* p = path; + char part[128]; + + while (tmpfs_split_next(&p, part, sizeof(part))) { + struct tmpfs_node* next = tmpfs_child_ensure_dir(cur, part); + if (!next) return -1; + cur = next; + } + + return 0; +} + +fs_node_t* tmpfs_create_file(fs_node_t* root_dir, const char* path, const uint8_t* data, uint32_t len) { + if (!root_dir || root_dir->flags != FS_DIRECTORY) return NULL; + if (!path) return NULL; + + struct tmpfs_node* cur = (struct tmpfs_node*)root_dir; + const char* p = path; + char part[128]; + char leaf[128]; + leaf[0] = 0; + + while (tmpfs_split_next(&p, part, sizeof(part))) { + if (*p == 0) { + strcpy(leaf, part); + break; + } + struct tmpfs_node* next = tmpfs_child_ensure_dir(cur, part); + if (!next) return NULL; + cur = next; + } + + if (leaf[0] == 0) return NULL; + + struct tmpfs_node* existing = tmpfs_child_find(cur, leaf); + if (existing) { + if (existing->vfs.flags != FS_FILE) return NULL; + if (len && data) { + uint8_t* buf = (uint8_t*)kmalloc(len); + if (!buf) return NULL; + memcpy(buf, data, len); + (void)tmpfs_write_impl(&existing->vfs, 0, len, buf); + kfree(buf); + } + return &existing->vfs; + } + + struct tmpfs_node* f = tmpfs_node_alloc(leaf, FS_FILE); + if (!f) return NULL; + + f->vfs.read = &tmpfs_read_impl; + f->vfs.write = &tmpfs_write_impl; + f->vfs.open = 0; + f->vfs.close = 0; + f->vfs.finddir = 0; + + if (len && data) { + f->data = (uint8_t*)kmalloc(len); + if (!f->data) { + kfree(f); + return NULL; + } + memcpy(f->data, data, len); + f->cap = len; + f->vfs.length = len; + } + + tmpfs_child_add(cur, f); + return &f->vfs; +} diff --git a/user/init.c b/user/init.c index 2b9ffa9..aa3c1db 100644 --- a/user/init.c +++ b/user/init.c @@ -154,14 +154,14 @@ void _start(void) { static const char path[] = "/bin/init.elf"; int fd = sys_open(path, 0); if (fd < 0) { - sys_write(1, "[init] open failed\n", 18); + sys_write(1, "[init] open failed\n", (uint32_t)(sizeof("[init] open failed\n") - 1)); sys_exit(1); } uint8_t hdr[4]; int rd = sys_read(fd, hdr, (uint32_t)sizeof(hdr)); if (sys_close(fd) < 0) { - sys_write(1, "[init] close failed\n", 19); + sys_write(1, "[init] close failed\n", (uint32_t)(sizeof("[init] close failed\n") - 1)); sys_exit(1); } @@ -169,177 +169,262 @@ void _start(void) { sys_write(1, "[init] open/read/close OK (ELF magic)\n", (uint32_t)(sizeof("[init] open/read/close OK (ELF magic)\n") - 1)); } else { - sys_write(1, "[init] read failed or bad header\n", 30); + sys_write(1, "[init] read failed or bad header\n", + (uint32_t)(sizeof("[init] read failed or bad header\n") - 1)); sys_exit(1); } fd = sys_open("/bin/init.elf", 0); if (fd < 0) { - sys_write(1, "[init] open2 failed\n", 19); + sys_write(1, "[init] overlay open failed\n", + (uint32_t)(sizeof("[init] overlay open failed\n") - 1)); + sys_exit(1); + } + + uint8_t orig0 = 0; + if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_read(fd, &orig0, 1) != 1) { + sys_write(1, "[init] overlay read failed\n", + (uint32_t)(sizeof("[init] overlay read failed\n") - 1)); + sys_exit(1); + } + + uint8_t x = (uint8_t)(orig0 ^ 0xFF); + if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_write(fd, &x, 1) != 1) { + sys_write(1, "[init] overlay write failed\n", + (uint32_t)(sizeof("[init] overlay write failed\n") - 1)); + sys_exit(1); + } + + if (sys_close(fd) < 0) { + sys_write(1, "[init] overlay close failed\n", + (uint32_t)(sizeof("[init] overlay close failed\n") - 1)); + sys_exit(1); + } + + fd = sys_open("/bin/init.elf", 0); + if (fd < 0) { + sys_write(1, "[init] overlay open2 failed\n", + (uint32_t)(sizeof("[init] overlay open2 failed\n") - 1)); + sys_exit(1); + } + + uint8_t chk = 0; + if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_read(fd, &chk, 1) != 1 || chk != x) { + sys_write(1, "[init] overlay verify failed\n", + (uint32_t)(sizeof("[init] overlay verify failed\n") - 1)); + sys_exit(1); + } + + if (sys_lseek(fd, 0, SEEK_SET) < 0 || sys_write(fd, &orig0, 1) != 1) { + sys_write(1, "[init] overlay restore failed\n", + (uint32_t)(sizeof("[init] overlay restore failed\n") - 1)); + sys_exit(1); + } + + if (sys_close(fd) < 0) { + sys_write(1, "[init] overlay close2 failed\n", + (uint32_t)(sizeof("[init] overlay close2 failed\n") - 1)); + sys_exit(1); + } + + sys_write(1, "[init] overlay copy-up OK\n", + (uint32_t)(sizeof("[init] overlay copy-up OK\n") - 1)); + + fd = sys_open("/bin/init.elf", 0); + if (fd < 0) { + sys_write(1, "[init] open2 failed\n", (uint32_t)(sizeof("[init] open2 failed\n") - 1)); sys_exit(1); } struct stat st; if (sys_fstat(fd, &st) < 0) { - sys_write(1, "[init] fstat failed\n", 19); + sys_write(1, "[init] fstat failed\n", (uint32_t)(sizeof("[init] fstat failed\n") - 1)); sys_exit(1); } if ((st.st_mode & S_IFMT) != S_IFREG || st.st_size == 0) { - sys_write(1, "[init] fstat bad\n", 16); + sys_write(1, "[init] fstat bad\n", (uint32_t)(sizeof("[init] fstat bad\n") - 1)); sys_exit(1); } if (sys_lseek(fd, 0, SEEK_SET) < 0) { - sys_write(1, "[init] lseek set failed\n", 24); + sys_write(1, "[init] lseek set failed\n", + (uint32_t)(sizeof("[init] lseek set failed\n") - 1)); sys_exit(1); } uint8_t m2[4]; if (sys_read(fd, m2, 4) != 4) { - sys_write(1, "[init] read2 failed\n", 19); + sys_write(1, "[init] read2 failed\n", (uint32_t)(sizeof("[init] read2 failed\n") - 1)); sys_exit(1); } if (m2[0] != 0x7F || m2[1] != 'E' || m2[2] != 'L' || m2[3] != 'F') { - sys_write(1, "[init] lseek/read mismatch\n", 27); + sys_write(1, "[init] lseek/read mismatch\n", + (uint32_t)(sizeof("[init] lseek/read mismatch\n") - 1)); sys_exit(1); } if (sys_close(fd) < 0) { - sys_write(1, "[init] close2 failed\n", 20); + sys_write(1, "[init] close2 failed\n", (uint32_t)(sizeof("[init] close2 failed\n") - 1)); sys_exit(1); } if (sys_stat("/bin/init.elf", &st) < 0) { - sys_write(1, "[init] stat failed\n", 18); + sys_write(1, "[init] stat failed\n", (uint32_t)(sizeof("[init] stat failed\n") - 1)); sys_exit(1); } if ((st.st_mode & S_IFMT) != S_IFREG || st.st_size == 0) { - sys_write(1, "[init] stat bad\n", 15); + sys_write(1, "[init] stat bad\n", (uint32_t)(sizeof("[init] stat bad\n") - 1)); sys_exit(1); } - sys_write(1, "[init] lseek/stat/fstat OK\n", 27); + sys_write(1, "[init] lseek/stat/fstat OK\n", + (uint32_t)(sizeof("[init] lseek/stat/fstat OK\n") - 1)); fd = sys_open("/tmp/hello.txt", 0); if (fd < 0) { - sys_write(1, "[init] tmpfs open failed\n", 24); + sys_write(1, "[init] tmpfs open failed\n", + (uint32_t)(sizeof("[init] tmpfs open failed\n") - 1)); sys_exit(1); } if (sys_stat("/tmp/hello.txt", &st) < 0) { - sys_write(1, "[init] tmpfs stat failed\n", 24); + sys_write(1, "[init] tmpfs stat failed\n", + (uint32_t)(sizeof("[init] tmpfs stat failed\n") - 1)); sys_exit(1); } if ((st.st_mode & S_IFMT) != S_IFREG) { - sys_write(1, "[init] tmpfs stat not reg\n", 26); + sys_write(1, "[init] tmpfs stat not reg\n", + (uint32_t)(sizeof("[init] tmpfs stat not reg\n") - 1)); sys_exit(1); } if (st.st_size == 0) { - sys_write(1, "[init] tmpfs stat size 0\n", 25); + sys_write(1, "[init] tmpfs stat size 0\n", + (uint32_t)(sizeof("[init] tmpfs stat size 0\n") - 1)); sys_exit(1); } struct stat fst; if (sys_fstat(fd, &fst) < 0) { - sys_write(1, "[init] tmpfs fstat failed\n", 25); + sys_write(1, "[init] tmpfs fstat failed\n", + (uint32_t)(sizeof("[init] tmpfs fstat failed\n") - 1)); sys_exit(1); } if (fst.st_size != st.st_size) { - sys_write(1, "[init] tmpfs stat size mismatch\n", 31); + sys_write(1, "[init] tmpfs stat size mismatch\n", + (uint32_t)(sizeof("[init] tmpfs stat size mismatch\n") - 1)); sys_exit(1); } int end = sys_lseek(fd, 0, SEEK_END); if (end < 0 || (uint32_t)end != st.st_size) { - sys_write(1, "[init] tmpfs lseek end bad\n", 27); + sys_write(1, "[init] tmpfs lseek end bad\n", + (uint32_t)(sizeof("[init] tmpfs lseek end bad\n") - 1)); sys_exit(1); } uint8_t eofb; if (sys_read(fd, &eofb, 1) != 0) { - sys_write(1, "[init] tmpfs eof read bad\n", 27); + sys_write(1, "[init] tmpfs eof read bad\n", + (uint32_t)(sizeof("[init] tmpfs eof read bad\n") - 1)); sys_exit(1); } if (sys_lseek(fd, 0, 999) >= 0) { - sys_write(1, "[init] tmpfs lseek whence bad\n", 30); + sys_write(1, "[init] tmpfs lseek whence bad\n", + (uint32_t)(sizeof("[init] tmpfs lseek whence bad\n") - 1)); sys_exit(1); } if (sys_lseek(fd, 0, SEEK_SET) < 0) { - sys_write(1, "[init] tmpfs lseek set failed\n", 30); + sys_write(1, "[init] tmpfs lseek set failed\n", + (uint32_t)(sizeof("[init] tmpfs lseek set failed\n") - 1)); sys_exit(1); } uint8_t tbuf[6]; if (sys_read(fd, tbuf, 5) != 5) { - sys_write(1, "[init] tmpfs read failed\n", 24); + sys_write(1, "[init] tmpfs read failed\n", + (uint32_t)(sizeof("[init] tmpfs read failed\n") - 1)); sys_exit(1); } tbuf[5] = 0; if (tbuf[0] != 'h' || tbuf[1] != 'e' || tbuf[2] != 'l' || tbuf[3] != 'l' || tbuf[4] != 'o') { - sys_write(1, "[init] tmpfs bad data\n", 22); + sys_write(1, "[init] tmpfs bad data\n", (uint32_t)(sizeof("[init] tmpfs bad data\n") - 1)); sys_exit(1); } if (sys_close(fd) < 0) { - sys_write(1, "[init] tmpfs close failed\n", 25); + sys_write(1, "[init] tmpfs close failed\n", + (uint32_t)(sizeof("[init] tmpfs close failed\n") - 1)); sys_exit(1); } if (sys_open("/tmp/does_not_exist", 0) >= 0) { - sys_write(1, "[init] tmpfs open nonexist bad\n", 32); + sys_write(1, "[init] tmpfs open nonexist bad\n", + (uint32_t)(sizeof("[init] tmpfs open nonexist bad\n") - 1)); sys_exit(1); } fd = sys_open("/tmp/hello.txt", 0); if (fd < 0) { - sys_write(1, "[init] tmpfs open3 failed\n", 25); + sys_write(1, "[init] tmpfs open3 failed\n", + (uint32_t)(sizeof("[init] tmpfs open3 failed\n") - 1)); sys_exit(1); } if (sys_fstat(fd, &fst) < 0) { - sys_write(1, "[init] tmpfs fstat2 failed\n", 26); + sys_write(1, "[init] tmpfs fstat2 failed\n", + (uint32_t)(sizeof("[init] tmpfs fstat2 failed\n") - 1)); sys_exit(1); } if (sys_lseek(fd, 0, SEEK_END) < 0) { - sys_write(1, "[init] tmpfs lseek end2 failed\n", 31); + sys_write(1, "[init] tmpfs lseek end2 failed\n", + (uint32_t)(sizeof("[init] tmpfs lseek end2 failed\n") - 1)); sys_exit(1); } - static const char suf[] = "XYZ"; + char suf[3]; + suf[0] = 'X'; + suf[1] = 'Y'; + suf[2] = 'Z'; if (sys_write(fd, suf, 3) != 3) { - sys_write(1, "[init] tmpfs write failed\n", 25); + sys_write(1, "[init] tmpfs write failed\n", + (uint32_t)(sizeof("[init] tmpfs write failed\n") - 1)); sys_exit(1); } if (sys_fstat(fd, &fst) < 0) { - sys_write(1, "[init] tmpfs fstat3 failed\n", 26); + sys_write(1, "[init] tmpfs fstat3 failed\n", + (uint32_t)(sizeof("[init] tmpfs fstat3 failed\n") - 1)); sys_exit(1); } if (fst.st_size != st.st_size + 3) { - sys_write(1, "[init] tmpfs size not grown\n", 27); + sys_write(1, "[init] tmpfs size not grown\n", + (uint32_t)(sizeof("[init] tmpfs size not grown\n") - 1)); sys_exit(1); } if (sys_lseek(fd, -3, SEEK_END) < 0) { - sys_write(1, "[init] tmpfs lseek back failed\n", 31); + sys_write(1, "[init] tmpfs lseek back failed\n", + (uint32_t)(sizeof("[init] tmpfs lseek back failed\n") - 1)); sys_exit(1); } uint8_t s2[3]; if (sys_read(fd, s2, 3) != 3 || s2[0] != 'X' || s2[1] != 'Y' || s2[2] != 'Z') { - sys_write(1, "[init] tmpfs suffix mismatch\n", 27); + sys_write(1, "[init] tmpfs suffix mismatch\n", + (uint32_t)(sizeof("[init] tmpfs suffix mismatch\n") - 1)); sys_exit(1); } if (sys_close(fd) < 0) { - sys_write(1, "[init] tmpfs close3 failed\n", 26); + sys_write(1, "[init] tmpfs close3 failed\n", + (uint32_t)(sizeof("[init] tmpfs close3 failed\n") - 1)); sys_exit(1); } - sys_write(1, "[init] tmpfs/mount OK\n", 22); + sys_write(1, "[init] tmpfs/mount OK\n", (uint32_t)(sizeof("[init] tmpfs/mount OK\n") - 1)); enum { NCHILD = 100 }; int children[NCHILD];