4 #include <linux/loop.h>
13 //#define PREFIX "/boot"
14 #define SQUASHFS_FILENAME PREFIX"/mnt/flash/squashfs"
16 #define streq(a,b) (strcmp((a),(b)) == 0)
18 /* This really needs to be in a header file... */
19 extern long init_module(void *, unsigned long, const char *);
21 /* We use error numbers in a loose translation... */
22 static const char *moderror(int err)
26 return "Invalid module format";
28 return "Unknown symbol in module";
30 return "Module has wrong symbol version";
32 return "Invalid parameters";
38 static void *grab_file(const char *filename, unsigned long *size)
40 unsigned int max = 16384;
42 void *buffer = malloc(max);
44 if (streq(filename, "-"))
45 fd = dup(STDIN_FILENO);
47 fd = open(filename, O_RDONLY, 0);
53 while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
56 buffer = realloc(buffer, max *= 2);
67 int insmod(const char *filename)
74 file = grab_file(filename, &len);
76 fprintf(stderr, "insmod: can't read '%s': %s\n",
77 filename, strerror(errno));
81 ret = init_module(file, len, "");
83 fprintf(stderr, "insmod: error inserting '%s': %li %s\n",
84 filename, ret, moderror(errno));
90 int main(int argc, char *argv[], char *envp[])
94 /* first, load some needed kernel modules located in the root of our boot partition */
95 const char *modules[] = { "fs/squashfs/unlzma.ko", "fs/squashfs/sqlzma.ko", "fs/squashfs/squashfs.ko", "fs/unionfs.ko", "drivers/block/loop.ko", 0 };
96 const char *modules_path = PREFIX"/lib/modules/2.6.12.6/kernel/";
99 printf("Hello world!\n");
103 strcpy(path, modules_path);
104 strcat(path, modules[x++]);
105 printf("insmodding %s..\n", path);
110 /* mount the RW jffs2 partition, which contains the squashfs image (in /squashfs) and the deltas (in /delta) */
111 printf("mounting mtd...\n");
112 res = mount("/dev/mtdblock/3", PREFIX"/mnt/flash", "jffs2", 0, 0);
116 perror("mounting /flash");
120 /* loop-mount the squashfs, by first connecting the file to loop0 ... */
121 printf("opening squashfs...\n");
122 int squashfs_fd = open(SQUASHFS_FILENAME, O_RDONLY);
125 perror(SQUASHFS_FILENAME);
129 printf("setup loop\n");
130 int loop_fd = open("/dev/loop/0", O_RDONLY);
134 perror("/dev/loop/0");
138 struct loop_info loopinfo;
140 memset(&loopinfo, 0, sizeof(loopinfo));
141 strncpy(loopinfo.lo_name, SQUASHFS_FILENAME, LO_NAME_SIZE);
142 loopinfo.lo_offset = 0;
143 loopinfo.lo_encrypt_key_size = 0;
144 if (ioctl(loop_fd, LOOP_SET_FD, (void*)squashfs_fd) < 0) {
145 perror("LOOP_SET_FD");
148 if (ioctl(loop_fd, LOOP_SET_STATUS, &loopinfo) < 0) {
149 perror("LOOP_SET_STATUS");
155 printf("mounting squashfs..\n");
157 /* and then mounting the loop device. */
158 if (mount("/dev/loop/0", PREFIX"/mnt/squashfs", "squashfs", MS_MGC_VAL|MS_RDONLY, "") < 0)
160 perror("mounting squashfs");
164 /* now the situation is:
166 / - our boot jffs2 partition
167 /flash - our RW jffs2 partition
168 /flash/squashfs - our loop-mounted squashfs file,
169 /flash/delta - the delta for the root
171 /root - yet empty, but we will populate it using unionfs
175 printf("mounting unionfs..\n");
176 res = mount("none", PREFIX"/mnt/root", "unionfs", MS_MGC_VAL, "dirs="PREFIX"/mnt/flash/delta=rw:"PREFIX"/mnt/squashfs=ro");
179 perror("mounting unionfs");
183 printf("pivot_root\n");
184 if ( pivot_root(PREFIX"/mnt/root", PREFIX"/mnt/root/boot") < 0)
186 perror("pivot_root");
190 printf("mounting devfs..\n");
191 res = mount("none", "/dev", "devfs", 0, 0);
194 perror("mounting /dev");
198 printf("try umount old devfs..\n");
199 res = umount("/boot/dev");
200 perror("umount /boot/dev");
202 printf("call init!\n");
203 execve("/sbin/init", argv, envp);
204 perror("/sbin/init");