9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a73d314881fdc996e2649e6154e6f6d6654bb05d
parent 7e6205016c51cfd5ee86c1ca4b7b2492ddcc989c
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Thu, 28 Feb 2019 10:28:04 +0000

[dev] Add devblob

This device exports in #b a filesystem that presents
blobs as files. The blobs can be incorporated to the
binary using a new section in the config file called
blobs. Anyway, a blob can be exported without linking
the program with the actual blob, but it requires
a phy with the data of the blob. When blobs are generated
and linked in the program using the config file then
the phy is automatically created. The device also
presents a ctl file to inspect and add new blobs.

Change-Id: Id0530c074afae7e7e55b80384556fb5651ca94d0

Diffstat:
Mdrivers/.gitignore | 1+
Mdrivers/Makefile | 5++++-
Mdrivers/Makefile.drv | 3++-
Adrivers/blob.h | 10++++++++++
Adrivers/devblob.c | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdrivers/devroot.c | 3+++
Adrivers/dump | 25+++++++++++++++++++++++++
Adrivers/mkblob | 24++++++++++++++++++++++++
Mdrivers/mkdev | 14++++++--------
Mdrivers/mkdevc | 22++++++++++------------
Adrivers/section | 10++++++++++
Minclude/rcode/9p.h | 2+-
Mtarget/hosted/rcode | 5+++++
Mtarget/hosted/rom.c | 8+++++++-
Mtarget/native/rcode | 1+
15 files changed, 272 insertions(+), 24 deletions(-)

diff --git a/drivers/.gitignore b/drivers/.gitignore @@ -1,2 +1,3 @@ devs.mk devc.c +blobs.mk diff --git a/drivers/Makefile b/drivers/Makefile @@ -2,8 +2,11 @@ PROJECTDIR=.. include $(PROJECTDIR)/scripts/rules.mk -all clean: devs.mk +all clean: devs.mk blobs.mk $(MAKE) -f Makefile.drv $@ devs.mk: $(TARGETDIR)/rcode mkdev $(TARGETDIR)/rcode + +blobs.mk: $(TARGETDIR)/rcode + mkblob $(TARGETDIR)/rcode diff --git a/drivers/Makefile.drv b/drivers/Makefile.drv @@ -2,6 +2,7 @@ PROJECTDIR=.. include $(PROJECTDIR)/scripts/rules.mk include devs.mk +include blobs.mk OBJS = $(DEVS) \ devc.o \ @@ -15,4 +16,4 @@ devc.c: $(TARGETDIR)/rcode mkdevc $(TARGETDIR)/rcode clean: - rm -f devs.mk devc.c + rm -f $(BLOBS) blobs.mk devs.mk devc.c diff --git a/drivers/blob.h b/drivers/blob.h @@ -0,0 +1,10 @@ +typedef struct blobphy Blobphy; + +struct attr; + +struct blobphy { + void *addr; + size_t size; +}; + +extern void bloblink(Blobphy *phy, struct attr *attr); diff --git a/drivers/devblob.c b/drivers/devblob.c @@ -0,0 +1,163 @@ +#include <stdlib.h> +#include <string.h> + +#include <libk.h> + +#include <rcode/rcode.h> +#include <rcode/9p.h> + +#include "dev.h" +#include "blob.h" + +#define NR_BLOBS 2 + +enum Orootqid { + Qblobfs, + Qctl, +}; + +static Dirtab blobfstab[NR_BLOBS+1] = { + {"ctl", Qctl, 0, O_READ | O_WRITE}, +}; + +static void *addrtab[NR_BLOBS+1]; +static int nblobs; + +static int +blobwalk(Chan *c, const char *name) +{ + if ((c->qid & ~CHDIR) != Qblobfs) + return 0; + return devwalk(c, name, blobfstab, nblobs+1, devgen); +} + +static Chan * +blobattach(int dev) +{ + return devattach('b', dev); +} + +static int +blobread(Chan *c, void *buf, int n) +{ + Qid qid; + int i; + size_t length; + char *addr; + Dirtab *dp; + char info[NR_BLOBS * (NAMELEN + 20)]; + + switch (c->qid & ~CHDIR) { + case Qblobfs: + return dirread(c, buf, n, blobfstab, nblobs+1, devgen); + case Qctl: + for (length = i = 0; i < nblobs; i++) { + dp = &blobfstab[i+1]; + length += ksnprint(info+length, + sizeof(info) - length, + "%s 0x%p %llu\n", + dp->name, + addrtab[i], + dp->length); + } + addr = info; + break; + default: + qid = c->qid; + if (qid - (Qctl + 1) > nblobs) + panic("bioread"); + qid -= 1; + dp = &blobfstab[qid]; + qid -= Qctl; + addr = addrtab[qid]; + + length = dp->length; + break; + } + + if (c->offset >= length) + return 0; + + if (c->offset + n > length) + n = length - c->offset; + + memcpy(buf, addr + c->offset, n); + + c->offset += n; + + return n; +} + +static int +newblob(char *name, void *addr, size_t len) +{ + Qid qid; + Dirtab *dp; + + if (nblobs == NR_BLOBS || strlen(name) >= NAMELEN) + return 0; + + addrtab[nblobs] = addr; + qid = nblobs + Qctl + 1; + dp = &blobfstab[qid-1]; + dp->qid = qid; + dp->perm = O_READ; + dp->length = len; + strcpy(dp->name, name); + nblobs++; + + return 1; +} + +void +bloblink(Blobphy *phy, Attr *attr) +{ + Attr *p; + + for (p = attr; p->key && strcmp(p->key, "file"); p++) + ; + + if (!p->key || !newblob(p->value, phy->addr, phy->size)) + panic("bloblink"); +} + +static int +blobwrite(Chan *c, void *buf, int n) +{ + char line[100], *name, *addr, *size; + void *p; + size_t s; + + if (c->qid != Qctl) + return -1; + + if (n > sizeof(buf)-1) + return -1; + memcpy(line, buf, n); + line[n] = '\0'; + + name = strtok(buf, " \t\r"); + addr = strtok(NULL, " \t\r"); + size = strtok(NULL, " \t\r"); + + if (!name || !addr || !size) + return -1; + + p = (void *) strtoll(addr, NULL, 0); + s = strtoll(size, NULL, 0); + if (!newblob(name, p, s)) + return -1; + + return n; +} + +const Dev blobdevtab = { + .id = 'b', + .name = "blob", + .clone = devclone, + .attach = blobattach, + .walk = blobwalk, + .read = blobread, + .write = blobwrite, + .bind = devbind, +}; diff --git a/drivers/devroot.c b/drivers/devroot.c @@ -8,12 +8,14 @@ enum Orootqid { Qdev, Qdevuart, Qrealm, + Qblobs, Qmax, }; static const Dirtab dirtab[] = { {"dev", CHDIR | Qdev, 0, O_READ}, {"realm", CHDIR | Qrealm, 0, O_READ}, + {"blobs", CHDIR | Qblobs, 0, O_READ}, }; static const Dirtab devfstab[] = { @@ -34,6 +36,7 @@ rootgen(Chan *c, const Dirtab *tab, int ntab, int n, Dir *dir) tab = devfstab; ntab = NELEM(devfstab); break; + case Qblobs: case Qdevuart: case Qrealm: return 0; diff --git a/drivers/dump b/drivers/dump @@ -0,0 +1,25 @@ +#!/bin/sh + +set -e +trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM + +file=$1 +sym=$2 + +cat <<EOF > $$.tmp && mv $$.tmp $sym.c +#include <stddef.h> + +#include "blob.h" + +`od -td1 -v -A n $file | +tr ' \t' '\n' | +awk -v sym=$sym ' +BEGIN {printf "char %s[] = {\n", sym} +NF == 1 {printf "\t%d,\n", $1} +END {print "};"}'` + +Blobphy ${sym}phy = { + .addr = $sym, + .size = sizeof($sym), +}; +EOF diff --git a/drivers/mkblob b/drivers/mkblob @@ -0,0 +1,24 @@ +#!/bin/sh + +trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM + +section blob $@ | +awk '{blobs[$1] = $2} +END {mkvar() + mkrules()} + +function mkvar() +{ + print "BLOBS = \\" + for (i in blobs) + printf "\t%s.c\n", i +} + +function mkrules() +{ + for (i in blobs) { + printf "%s.c: %s\n", i, blobs[i] + printf "\tdump %s %s\n", blobs[i], i + } +} +' > $$.tmp && mv $$.tmp blobs.mk diff --git a/drivers/mkdev b/drivers/mkdev @@ -2,13 +2,11 @@ trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM -sed 's/#.*//' $@ | +section dev $@ | awk ' -BEGIN {print "DEVS = dev.o\\"} -/^[ \t]*$/ {next} -/^dev/ {indev = 1; next} -/^\t\t/ {objs[$1 ".o"] = 1; next} -indev && /^\t/ {objs["dev" $1 ".o"] = 1; next} -END {for (i in objs) - printf "\t%s\\\n", i}' > $$.tmp && +BEGIN {print "DEVS = dev.o\\"} +/^\t\t/ {objs[$1 ".o"] = 1; next} +/^\t/ {objs["dev" $1 ".o"] = 1; next} +END {for (i in objs) + printf "\t%s\\\n", i}' > $$.tmp && mv $$.tmp devs.mk diff --git a/drivers/mkdevc b/drivers/mkdevc @@ -2,19 +2,17 @@ trap 'r=$?; rm -f $$.tmp; exit $r' EXIT HUP INT QUIT TERM -sed -e 's/^#.*//' -e '/^[ \t]*$/d' $@ | +section dev $@ | awk ' -/^[ \t]*$/ {next} -/^dev/ {indev = 1; next} -indev && /^\t\t/ {devs[dev]++ - phys[$1] = dev - drivers[n++] = dev FS $1 FS $2} -indev && /^\t[^\t]/ {dev = $1 - devs[dev] = 0} -END {typedef() - extern() - devtab() - devlink()} +/^\t\t/ {devs[dev]++ + phys[$1] = dev + drivers[n++] = dev FS $1 FS $2 + next} +/^\t/ {devs[dev = $1] = 0} +END {typedef() + extern() + devtab() + devlink()} function capital(x) { diff --git a/drivers/section b/drivers/section @@ -0,0 +1,10 @@ +#!/bin/sh + +sect=$1 +shift + +sed -n 's/^#.*// + /^[ ]*$/d + /^'$sect'/,/^[^ ]/ { + /^ /p + }' $@ diff --git a/include/rcode/9p.h b/include/rcode/9p.h @@ -1,7 +1,7 @@ #ifndef LIBK_H_ #define LIBK_H_ -#define NAMELEN 8 +#define NAMELEN 14 #define STATLEN 41 #define ROOTLEN (2 + 4) #define FILNAMLEN (2 + NAMELEN) diff --git a/target/hosted/rcode b/target/hosted/rcode @@ -3,3 +3,8 @@ dev uart pl011 base=0x1c0c0000,clk=24000000,cfg=b115200 l8 pl011 base=0x1c0c0100,clk=24000000 + blob + example file=example.tar +blob + example ../target/hosted/example.tar +end diff --git a/target/hosted/rom.c b/target/hosted/rom.c @@ -43,7 +43,13 @@ static void namespace(void) { if (bind("#t0", "/dev/uart") < 0) - kerror("namespace"); + goto error; + if (bind("#b", "/blobs") < 0) + goto error; + return; + +error: + kerror("namespace"); } int diff --git a/target/native/rcode b/target/native/rcode @@ -3,3 +3,4 @@ dev uart pl011 base=0x1c0c0000,clk=24000000,rate=115200 pl011 base=0x1c0c0100,clk=24000000,rate=115200 +end