CPIO support for KFS
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 5 Jun 2010 03:58:13 +0000 (20:58 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:47 +0000 (17:35 -0700)
Basic support to understand CPIO archives for an initramfs.  There is
some rudimentary support in the Makefile mess to build the initramfs
based on some variables in Makelocal.  If you want to strip the binaries
before adding them, do it in a tools script.  For whatever bullshit
Makefile reason, it's a pain doing that in tests/Makefrag.

GNUmakefile
Makelocal.template
kern/include/cpio.h [new file with mode: 0644]
kern/src/Makefrag
kern/src/kfs.c
tests/Makefrag

index 8009111..b4a2109 100644 (file)
@@ -46,7 +46,7 @@ MAKE_JOBS :=
 include Makeconfig
 -include Makelocal
 
-TOP_DIR := .
+TOP_DIR := $(shell pwd)
 ARCH_DIR := $(TOP_DIR)/kern/arch
 INCLUDE_DIR := $(TOP_DIR)/kern/include
 DOXYGEN_DIR := $(TOP_DIR)/Documentation/doxygen
index 4ec5100..5fe097f 100644 (file)
 #KERN_CFLAGS += -DDEVELOPER_NAME=waterman
 #KERN_CFLAGS += -DDEVELOPER_NAME=brho
 
+
+# Paths for the initramfs (need to be directories)
+#INITRAMFS_PATHS = kern/kfs obj/tests
+# Program to execute before building the initramfs
+#INITRAMFS_BIN = tools/whatever.sh
+
 # Userspace configuration parameters
 #USER_CFLAGS += $(CONFIG_SYSCALL_TRAP)
 #USER_CFLAGS += $(CONFIG_USER_DEBUGINFO)
diff --git a/kern/include/cpio.h b/kern/include/cpio.h
new file mode 100644 (file)
index 0000000..5fbb08e
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef ROS_KERN_CPIO_H
+#define ROS_KERN_CPIO_H
+
+#define CPIO_NEW_ASCII 070701
+#define CPIO_CRC_ASCII 070702
+
+struct cpio_newc_header
+{
+       char c_magic[6];
+       char c_ino[8];
+       char c_mode[8];
+       char c_uid[8];
+       char c_gid[8];
+       char c_nlink[8];
+       char c_mtime[8];
+       char c_filesize[8];     /* must be 0 for FIFOs and directories */
+       char c_dev_maj[8];
+       char c_dev_min[8];
+       char c_rdev_maj[8];     /* only valid for chr and blk special files */
+       char c_rdev_min[8];     /* only valid for chr and blk special files */
+       char c_namesize[8];     /* count includes terminating NUL in pathname */
+       char c_chksum[8];       /* for CRC format the sum of all the bytes in the file*/
+};
+
+void print_cpio_entries(void *cpio_b);
+
+#endif /* ROS_KERN_CPIO_H */
index 822a531..da8639b 100644 (file)
@@ -6,6 +6,7 @@
 
 KERN_SRC_DIR = $(KERN_DIR)/src
 OBJDIRS += $(KERN_SRC_DIR)
+KERN_CPIO = initramfs.cpio
 
 # entry.S must be first, so that it's the first code in the text segment!!!
 #
@@ -85,12 +86,26 @@ KERN_APPFILES  := $(patsubst %, $(OBJDIR)/%, $(KERN_APPFILES))
 KERN_RAWAPPFILES  := $(KERN_DIR)/kfs/*
 
 KERN_LDDEPENDS := $(KERN_OBJFILES) $(KERN_APPFILES) $(ARCH_DIR)/$(TARGET_ARCH)/kernel.ld \
-                  $(OBJDIR)/$(KERN_DIR)/libivykern.a
+                  $(OBJDIR)/$(KERN_DIR)/libivykern.a $(OBJDIR)/$(KERN_DIR)/$(KERN_CPIO)
 
 KERN_LDLIBS    := -livykern
 
 KERN_GCC_LIB   ?= $(GCC_LIB)
 
+KERN_INITRAMFS_FILES := $(shell mkdir -p $(INITRAMFS_PATHS); find $(INITRAMFS_PATHS))
+
+$(OBJDIR)/$(KERN_DIR)/$(KERN_CPIO) initramfs: $(KERN_INITRAMFS_FILES)
+       @echo Building initramfs:
+       @if [ "$(INITRAMFS_BIN)" != "" ]; then \
+        sh $(INITRAMFS_BIN); \
+    fi
+       $(V)for i in $(INITRAMFS_PATHS); do cd $$i; \
+        echo Adding $$i to initramfs...; \
+        find -L . -depth | cpio --quiet -oH newc > \
+             $(TOP_DIR)/$(OBJDIR)/$(KERN_DIR)/$(KERN_CPIO); \
+        cd $$OLDPWD; \
+    done;
+
 $(OBJDIR)/$(KERN_DIR)/%.o: $(KERN_DIR)/%.c
        @echo + cc [KERN] $<
        @mkdir -p $(@D)
@@ -108,7 +123,8 @@ $(OBJDIR)/$(KERN_DIR)/kernel: $(KERN_LDDEPENDS)
                $(STRIP) -s $(KERN_APPFILES) ; \
        fi
        $(V)$(LD) -o $@ $(KERN_LDFLAGS) $(KERN_OBJFILES) $(KERN_LDLIBS) \
-                       $(KERN_GCC_LIB) -b binary $(KERN_APPFILES) $(KERN_RAWAPPFILES)
+                       $(KERN_GCC_LIB) -b binary $(KERN_APPFILES) $(KERN_RAWAPPFILES) \
+                       $(OBJDIR)/$(KERN_DIR)/$(KERN_CPIO)
        $(V)$(OBJDUMP) -S $@ > $@.asm
        $(V)$(NM) -n $@ > $@.sym
 
index 8d46275..c77592c 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <error.h>
+#include <cpio.h>
 
 #define KFS_MAX_FILE_SIZE 1024*1024*128
 #define KFS_MAGIC 0xdead0001
@@ -59,10 +60,18 @@ struct super_block *kfs_get_sb(struct fs_type *fs, int flags,
        sb->s_syncing = FALSE;
        sb->s_bdev = 0;
        strlcpy(sb->s_name, "KFS", 32);
-       //sb->s_fs_info = 0; /* nothing to override with for KFS */
+       /* store the location of the CPIO archive.  make this more generic later. */
+       extern uint8_t _binary_obj_kern_initramfs_cpio_size[];
+       extern uint8_t _binary_obj_kern_initramfs_cpio_start[];
+       sb->s_fs_info = (void*)_binary_obj_kern_initramfs_cpio_start;
+
        /* Final stages of initializing the sb, mostly FS-independent */
        init_sb(sb, vmnt, &kfs_d_op, 1); /* 1 is the KFS root ino (inode number) */
        printk("KFS superblock loaded\n");
+
+       /* Or whatever.  For now, just check to see the archive worked. */
+       print_cpio_entries(sb->s_fs_info);
+
        return sb;
 }
 
@@ -641,3 +650,39 @@ void kfs_cat(int kfs_inode)
        for (uint8_t *ptr = kfs[kfs_inode].start; ptr < end; ptr++)
                cputchar(*ptr);
 }
+
+void print_cpio_entries(void *cpio_b)
+{
+       struct cpio_newc_header *c_hdr = (struct cpio_newc_header*)cpio_b;
+
+       char buf[9] = {0};      /* temp space for strol conversions */
+       int size = 0;
+       int offset = 0;         /* offset in the cpio archive */
+
+       /* read all files and paths */
+       for (; ; c_hdr = (struct cpio_newc_header*)(cpio_b + offset)) {
+               offset += sizeof(*c_hdr);
+               printk("magic: %.6s\n", c_hdr->c_magic);
+               printk("namesize: %.8s\n", c_hdr->c_namesize);
+               printk("filesize: %.8s\n", c_hdr->c_filesize);
+               memcpy(buf, c_hdr->c_namesize, 8);
+               buf[8] = '\0';
+               size = strtol(buf, 0, 16);
+               printk("Namesize: %d\n", size);
+               printk("Filename: %s\n", (char*)c_hdr + sizeof(*c_hdr));
+               if (!strcmp((char*)c_hdr + sizeof(*c_hdr), "TRAILER!!!"))
+                       break;
+               offset += size;
+               /* header + name will be padded out to 4-byte alignment */
+               offset = ROUNDUP(offset, 4);
+               memcpy(buf, c_hdr->c_filesize, 8);
+               buf[8] = '\0';
+               size = strtol(buf, 0, 16);
+               printk("Filesize: %d\n", size);
+               offset += size;
+               offset = ROUNDUP(offset, 4);
+               //printk("offset is %d bytes\n", offset);
+               c_hdr = (struct cpio_newc_header*)(cpio_b + offset);
+               printk("\n");
+       }
+}
index cd04fa1..587095a 100644 (file)
@@ -8,7 +8,7 @@ ALL_TEST_FILES = $(shell ls $(TESTS_DIR)/*.c)
 
 TESTS_LDDIRS := -L$(OBJDIR)/$(USER_PARLIB_DIR)
 
-TESTS_LDLIBS := -lparlib 
+TESTS_LDLIBS := -lparlib
 
 TESTS_SRCS := $(ALL_TEST_FILES)