1 | /*
|
---|
2 | loadramdisk.c
|
---|
3 |
|
---|
4 | Copy a device or file specified as argument to /dev/ram
|
---|
5 | */
|
---|
6 |
|
---|
7 | #include <errno.h>
|
---|
8 | #include <fcntl.h>
|
---|
9 | #include <stdio.h>
|
---|
10 | #include <stdlib.h>
|
---|
11 | #include <string.h>
|
---|
12 | #include <unistd.h>
|
---|
13 | #include <sys/ioctl.h>
|
---|
14 |
|
---|
15 | #define RAM "/dev/ram"
|
---|
16 |
|
---|
17 | char buf[10240];
|
---|
18 |
|
---|
19 | static unsigned long size_device(int fd);
|
---|
20 |
|
---|
21 | int main(int argc, char *argv[])
|
---|
22 | {
|
---|
23 | unsigned long off, size;
|
---|
24 | int r, s, fd, ramfd;
|
---|
25 | char *src;
|
---|
26 |
|
---|
27 | if (argc != 2)
|
---|
28 | {
|
---|
29 | fprintf(stderr, "Usage: loadramdisk <file>\n");
|
---|
30 | exit(1);
|
---|
31 | }
|
---|
32 | src= argv[1];
|
---|
33 | fd= open(src, O_RDONLY);
|
---|
34 | if (fd < 0)
|
---|
35 | {
|
---|
36 | fprintf(stderr, "Unable to open '%s': %s\n",
|
---|
37 | src, strerror(errno));
|
---|
38 | exit(1);
|
---|
39 | }
|
---|
40 |
|
---|
41 | /* Get the size of the device */
|
---|
42 | errno= 0;
|
---|
43 | size= size_device(fd);
|
---|
44 | if (errno != 0)
|
---|
45 | {
|
---|
46 | fprintf(stderr, "Lseek(end) failed on '%s': %s\n",
|
---|
47 | src, strerror(errno));
|
---|
48 | exit(1);
|
---|
49 | }
|
---|
50 | if (lseek(fd, 0, SEEK_SET) != 0)
|
---|
51 | {
|
---|
52 | fprintf(stderr, "Lseek(0) failed on '%s': %s\n",
|
---|
53 | src, strerror(errno));
|
---|
54 | exit(1);
|
---|
55 | }
|
---|
56 |
|
---|
57 | ramfd= open(RAM, O_RDWR);
|
---|
58 | if (ramfd < 0)
|
---|
59 | {
|
---|
60 | fprintf(stderr, "Unable to open '%s': %s\n",
|
---|
61 | RAM, strerror(errno));
|
---|
62 | exit(1);
|
---|
63 | }
|
---|
64 | r= ioctl(ramfd, MIOCRAMSIZE, &size);
|
---|
65 | if (r != 0)
|
---|
66 | {
|
---|
67 | fprintf(stderr, "MIOCRAMSIZE %lu failed on '%s': %s\n",
|
---|
68 | size, RAM, strerror(errno));
|
---|
69 | exit(1);
|
---|
70 | }
|
---|
71 |
|
---|
72 | off= 0;
|
---|
73 | while (off < size)
|
---|
74 | {
|
---|
75 | r= read(fd, buf, sizeof(buf));
|
---|
76 | if (r <= 0)
|
---|
77 | {
|
---|
78 | fprintf(stderr, "error reading '%s': %s\n",
|
---|
79 | src, r == 0 ? "unexpected EOF" :
|
---|
80 | strerror(errno));
|
---|
81 | exit(1);
|
---|
82 | }
|
---|
83 | s= write(ramfd, buf, r);
|
---|
84 | if (s != r)
|
---|
85 | {
|
---|
86 | fprintf(stderr, "error writing to '%s': %s\n",
|
---|
87 | s >= 0 ? "short write" : strerror(errno));
|
---|
88 | exit(1);
|
---|
89 | }
|
---|
90 | off += r;
|
---|
91 | }
|
---|
92 | exit(0);
|
---|
93 | }
|
---|
94 |
|
---|
95 | static unsigned long size_device(int fd)
|
---|
96 | {
|
---|
97 | char b;
|
---|
98 | int r;
|
---|
99 | unsigned long low, mid, high;
|
---|
100 |
|
---|
101 | /* Try to find the size of a device using binary search */
|
---|
102 | low= 0;
|
---|
103 | high= -1;
|
---|
104 |
|
---|
105 | while (mid= low+(high-low)/2, mid > low)
|
---|
106 | {
|
---|
107 | if (lseek(fd, mid, SEEK_SET) != mid)
|
---|
108 | {
|
---|
109 | fprintf(stderr, "lseek to %lu failed: %s\n",
|
---|
110 | mid, strerror(errno));
|
---|
111 | exit(1);
|
---|
112 | }
|
---|
113 | r= read(fd, &b, 1);
|
---|
114 | if (r < 0)
|
---|
115 | {
|
---|
116 | fprintf(stderr, "read failed at position %lu: %s\n",
|
---|
117 | mid, strerror(errno));
|
---|
118 | exit(1);
|
---|
119 | }
|
---|
120 | if (r > 0)
|
---|
121 | low= mid;
|
---|
122 | else
|
---|
123 | high= mid;
|
---|
124 | }
|
---|
125 | return high;
|
---|
126 | }
|
---|