1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "../port/error.h" 7 8 enum{ 9 Qdir= 0, 10 11 Nfiles=32, /* max root files */ 12 }; 13 14 extern ulong bootlen; 15 extern uchar bootcode[]; 16 17 Dirtab rootdir[Nfiles] = { 18 ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, 19 }; 20 21 static uchar *rootdata[Nfiles]; 22 static int nroot = 1; 23 24 /* 25 * add a root file 26 */ 27 static void 28 addroot(char *name, uchar *contents, ulong len, int perm) 29 { 30 Dirtab *d; 31 32 if(nroot >= Nfiles) 33 panic("too many root files"); 34 rootdata[nroot] = contents; 35 d = &rootdir[nroot]; 36 strcpy(d->name, name); 37 d->length = len; 38 d->perm = perm; 39 d->qid.type = 0; 40 d->qid.vers = 0; 41 d->qid.path = nroot+1; 42 if(perm & DMDIR) 43 d->qid.type |= QTDIR; 44 nroot++; 45 } 46 47 /* 48 * add a root file 49 */ 50 void 51 addrootfile(char *name, uchar *contents, ulong len) 52 { 53 addroot(name, contents, len, 0555); 54 } 55 56 /* 57 * add a root file 58 */ 59 static void 60 addrootdir(char *name) 61 { 62 addroot(name, nil, 0, DMDIR|0555); 63 } 64 65 static void 66 rootreset(void) 67 { 68 addrootdir("bin"); 69 addrootdir("dev"); 70 addrootdir("env"); 71 addrootdir("fd"); 72 addrootdir("mnt"); 73 addrootdir("net"); 74 addrootdir("net.alt"); 75 addrootdir("proc"); 76 addrootdir("root"); 77 addrootdir("srv"); 78 79 addrootfile("boot", bootcode, bootlen); /* always have a boot file */ 80 } 81 82 static Chan* 83 rootattach(char *spec) 84 { 85 return devattach('/', spec); 86 } 87 88 static Walkqid* 89 rootwalk(Chan *c, Chan *nc, char **name, int nname) 90 { 91 return devwalk(c, nc, name, nname, rootdir, nroot, devgen); 92 } 93 94 static int 95 rootstat(Chan *c, uchar *dp, int n) 96 { 97 return devstat(c, dp, n, rootdir, nroot, devgen); 98 } 99 100 static Chan* 101 rootopen(Chan *c, int omode) 102 { 103 switch((ulong)c->qid.path) { 104 default: 105 break; 106 } 107 108 return devopen(c, omode, rootdir, nroot, devgen); 109 } 110 111 /* 112 * sysremove() knows this is a nop 113 */ 114 static void 115 rootclose(Chan*) 116 { 117 } 118 119 static long 120 rootread(Chan *c, void *buf, long n, vlong off) 121 { 122 ulong t; 123 Dirtab *d; 124 uchar *data; 125 ulong offset = off; 126 127 t = c->qid.path; 128 switch(t){ 129 case Qdir: 130 return devdirread(c, buf, n, rootdir, nroot, devgen); 131 } 132 133 d = &rootdir[t-1]; 134 data = rootdata[t-1]; 135 if(offset >= d->length) 136 return 0; 137 if(offset+n > d->length) 138 n = d->length - offset; 139 memmove(buf, data+offset, n); 140 return n; 141 } 142 143 static long 144 rootwrite(Chan *c, void*, long, vlong) 145 { 146 switch((ulong)c->qid.path){ 147 default: 148 error(Egreg); 149 } 150 return 0; 151 } 152 153 Dev rootdevtab = { 154 '/', 155 "root", 156 157 rootreset, 158 devinit, 159 devshutdown, 160 rootattach, 161 rootwalk, 162 rootstat, 163 rootopen, 164 devcreate, 165 rootclose, 166 rootread, 167 devbread, 168 rootwrite, 169 devbwrite, 170 devremove, 171 devwstat, 172 }; 173