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", RAM, 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 } 127