-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinitrd.c
126 lines (106 loc) · 2.72 KB
/
initrd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// fs driver for the initial ramdsk
// single directory fs: file info is integrated into the header files
// Headers need to be translated to inodes
#include "common.h"
#include "initrd.h"
#include "file.h"
#include "fs.h"
//#include "defs.h"
extern uint32_t *initrd;
extern struct devsw devsw[];
struct inode *root;
struct initrdsb *sb;
struct initrdhdr *initrdhdrs;
struct rdbuf rdbuf[32];
void iinitrd(uint32_t *location)
{
struct inode *root;
sb = location;
initrdhdrs = (struct initrdhdr*)((uint32_t)location + sizeof(struct initrdsb));
//devsw[D_INITDR].read = readinitrd;
kprintf("initrd: sb: %h", sb->nfiles);
uint32_t loc = (uint32_t)location + (uint32_t)(*initrdhdrs).offset;
kprintf("iinitrd offset: %h", location);
kprintf("iinitrd offset: %h", initrdhdrs);
kprintf("iinitrd offset: %h", loc);
root = iget(1,1);
root->size = (uint32_t)sizeof(struct dirent) * sb->nfiles;
root->type = T_DIR;
}
struct rdbuf* rdget()
{
struct rdbuf *b;
b = &rdbuf;
while ( b->flags == B_BUSY && b < &rdbuf[32] )
b++;
if (b->flags == B_BUSY)
PANIC("rdget: No free buffers!");
b->flags == B_BUSY;
memset(b->data, 0, 512);
return b;
}
int rdrelse(struct rdbuf *b)
{
b->flags = 0;
return 0;
}
struct initrdhdr *getinitrdhdr(struct inode *ip)
{
// get the header that corresponds to the inode
struct initrdhdr *hdr;
hdr = initrdhdrs + (ip->inum - 2);
if(hdr->magic != 0xBF)
PANIC("updateinitrd: cannot find header!");
return hdr;
}
void getinitrd(struct inode *ip)
{
struct initrdhdr *hdr;
hdr = getinitrdhdr(ip);
ip->size = hdr->sz;
ip->addrs[0] = hdr->offset;
//kprintf("getinitrd: hdr->offset: %h",hdr->offset);
//kprintf("getinitrd: ip->addrs: %h",*ip->addrs);
}
struct rdbuf *readinitrd(struct inode *ip, uint32_t off, uint32_t n)
{
struct dirent *de;
struct rdbuf *b;
uint32_t nr;
char *offset;
b = rdget();
if(ip->inum == 1){
// Reading root: (e.g. searching)
// We should return the nth dirent entry...
nr = off / sizeof(struct dirent);
if (off % sizeof(struct dirent) !=0 || off > ip->size) {
PANIC("readinitrd: out of bounds offset");
}
nr = off / sizeof(struct dirent);
de = b->data;
de->inum = nr + 2; // 1 = root
safestrcpy(de->name, (initrdhdrs[nr]).name);
b->data[n] = 0;
return b;
} else {
// Reading a file
if((off + n) > ip->size)
PANIC("readinitrd: reading past end of file.");
offset = (uint32_t)sb + ip->addrs[0] + off;
//kprintf("readinitrd: offset: %h", n);
memmove(b->data, offset, n);
//b->data[n+1] = 0;
//kprintf("readinitrd: data>>>",0);
//fb_write(b->data);
//fb_write("<<<<<");
return b;
}
}
void updateinitrd(struct inode *ip)
{
struct initrdhdr *hdr;
hdr = getinitrdhdr(ip);
hdr->sz = ip->size;
hdr->magic = 0xBF;
hdr->offset = ip->addrs;
}