d8a7c4b116d99b548df433cf645728f4e4cabbd6
[akaros.git] / user / vmm / initrd.c
1 /* Copyright (c) 2017 Google Inc.
2  * See LICENSE for details.
3  *
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <err.h>
13
14 /* initrd loads the initrd and returns its place in the world. It has
15  * to avoid the already loaded kernel. */
16 ssize_t setup_initrd(char *filename, void *membase, size_t memsize)
17 {
18         int fd;
19         struct stat buf;
20         void *where = membase;
21         int amt;
22         int tot = 0;
23
24         if (!filename)
25                 return 0;
26
27         fd = open(filename, O_RDONLY);
28         if (fd < 0) {
29                 fprintf(stderr, "Can't open %s: %r\n", filename);
30                 return 0;
31         }
32
33         if (fstat(fd, &buf) < 0) {
34                 fprintf(stderr, "Can't stat %s: %r\n", filename);
35                 close(fd);
36                 return 0;
37         }
38
39         if (buf.st_size > memsize) {
40                 fprintf(stderr,
41                         "file is %d bytes, but we only have %d bytes to place it\n",
42                         buf.st_size, memsize);
43                 close(fd);
44                 return 0;
45         }
46
47         while (tot < buf.st_size) {
48                 amt = read(fd, where, buf.st_size - tot);
49                 if (amt < 0) {
50                         tot = 0;
51                         break;
52                 }
53                 where += amt;
54                 tot += amt;
55         }
56
57         close(fd);
58         return tot;
59 }