do_mounts.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:24k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #define __KERNEL_SYSCALLS__
  2. #include <linux/config.h>
  3. #include <linux/slab.h>
  4. #include <linux/devfs_fs_kernel.h>
  5. #include <linux/unistd.h>
  6. #include <linux/ctype.h>
  7. #include <linux/blk.h>
  8. #include <linux/fd.h>
  9. #include <linux/tty.h>
  10. #include <linux/init.h>
  11. #include <linux/nfs_fs.h>
  12. #include <linux/nfs_fs_sb.h>
  13. #include <linux/nfs_mount.h>
  14. #include <linux/minix_fs.h>
  15. #include <linux/ext2_fs.h>
  16. #include <linux/romfs_fs.h>
  17. #define BUILD_CRAMDISK
  18. extern int get_filesystem_list(char * buf);
  19. extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
  20.  unsigned long flags, void *data);
  21. extern asmlinkage long sys_mkdir(const char *name, int mode);
  22. extern asmlinkage long sys_chdir(const char *name);
  23. extern asmlinkage long sys_fchdir(int fd);
  24. extern asmlinkage long sys_chroot(const char *name);
  25. extern asmlinkage long sys_unlink(const char *name);
  26. extern asmlinkage long sys_symlink(const char *old, const char *new);
  27. extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
  28. extern asmlinkage long sys_umount(char *name, int flags);
  29. extern asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
  30. #ifdef CONFIG_BLK_DEV_INITRD
  31. unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
  32. static int __initdata mount_initrd = 1;
  33. static int __init no_initrd(char *str)
  34. {
  35. mount_initrd = 0;
  36. return 1;
  37. }
  38. __setup("noinitrd", no_initrd);
  39. #else
  40. static int __initdata mount_initrd = 0;
  41. #endif
  42. int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
  43. int root_mountflags = MS_RDONLY | MS_VERBOSE;
  44. static char root_device_name[64];
  45. /* this is initialized in init/main.c */
  46. kdev_t ROOT_DEV;
  47. static int do_devfs = 0;
  48. static int __init load_ramdisk(char *str)
  49. {
  50. rd_doload = simple_strtol(str,NULL,0) & 3;
  51. return 1;
  52. }
  53. __setup("load_ramdisk=", load_ramdisk);
  54. static int __init readonly(char *str)
  55. {
  56. if (*str)
  57. return 0;
  58. root_mountflags |= MS_RDONLY;
  59. return 1;
  60. }
  61. static int __init readwrite(char *str)
  62. {
  63. if (*str)
  64. return 0;
  65. root_mountflags &= ~MS_RDONLY;
  66. return 1;
  67. }
  68. __setup("ro", readonly);
  69. __setup("rw", readwrite);
  70. static struct dev_name_struct {
  71. const char *name;
  72. const int num;
  73. } root_dev_names[] __initdata = {
  74. { "nfs",     0x00ff },
  75. { "hda",     0x0300 },
  76. { "hdb",     0x0340 },
  77. { "loop",    0x0700 },
  78. { "hdc",     0x1600 },
  79. { "hdd",     0x1640 },
  80. { "hde",     0x2100 },
  81. { "hdf",     0x2140 },
  82. { "hdg",     0x2200 },
  83. { "hdh",     0x2240 },
  84. { "hdi",     0x3800 },
  85. { "hdj",     0x3840 },
  86. { "hdk",     0x3900 },
  87. { "hdl",     0x3940 },
  88. { "hdm",     0x5800 },
  89. { "hdn",     0x5840 },
  90. { "hdo",     0x5900 },
  91. { "hdp",     0x5940 },
  92. { "hdq",     0x5A00 },
  93. { "hdr",     0x5A40 },
  94. { "hds",     0x5B00 },
  95. { "hdt",     0x5B40 },
  96. { "sda",     0x0800 },
  97. { "sdb",     0x0810 },
  98. { "sdc",     0x0820 },
  99. { "sdd",     0x0830 },
  100. { "sde",     0x0840 },
  101. { "sdf",     0x0850 },
  102. { "sdg",     0x0860 },
  103. { "sdh",     0x0870 },
  104. { "sdi",     0x0880 },
  105. { "sdj",     0x0890 },
  106. { "sdk",     0x08a0 },
  107. { "sdl",     0x08b0 },
  108. { "sdm",     0x08c0 },
  109. { "sdn",     0x08d0 },
  110. { "sdo",     0x08e0 },
  111. { "sdp",     0x08f0 },
  112. { "ada",     0x1c00 },
  113. { "adb",     0x1c10 },
  114. { "adc",     0x1c20 },
  115. { "add",     0x1c30 },
  116. { "ade",     0x1c40 },
  117. { "fd",      0x0200 },
  118. { "md",      0x0900 },      
  119. { "xda",     0x0d00 },
  120. { "xdb",     0x0d40 },
  121. { "ram",     0x0100 },
  122. { "scd",     0x0b00 },
  123. { "mcd",     0x1700 },
  124. { "cdu535",  0x1800 },
  125. { "sonycd",  0x1800 },
  126. { "aztcd",   0x1d00 },
  127. { "cm206cd", 0x2000 },
  128. { "gscd",    0x1000 },
  129. { "sbpcd",   0x1900 },
  130. { "eda",     0x2400 },
  131. { "edb",     0x2440 },
  132. { "pda", 0x2d00 },
  133. { "pdb", 0x2d10 },
  134. { "pdc", 0x2d20 },
  135. { "pdd", 0x2d30 },
  136. { "pcd", 0x2e00 },
  137. { "pf", 0x2f00 },
  138. { "apblock", APBLOCK_MAJOR << 8},
  139. { "ddv", DDV_MAJOR << 8},
  140. { "jsfd",    JSFD_MAJOR << 8},
  141. #if defined(CONFIG_ARCH_S390)
  142. { "dasda", (DASD_MAJOR << MINORBITS) },
  143. { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
  144. { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
  145. { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
  146. { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
  147. { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
  148. { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
  149. { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
  150. #endif
  151. #if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
  152. { "ida/c0d0p",0x4800 },
  153. { "ida/c0d1p",0x4810 },
  154. { "ida/c0d2p",0x4820 },
  155. { "ida/c0d3p",0x4830 },
  156. { "ida/c0d4p",0x4840 },
  157. { "ida/c0d5p",0x4850 },
  158. { "ida/c0d6p",0x4860 },
  159. { "ida/c0d7p",0x4870 },
  160. { "ida/c0d8p",0x4880 },
  161. { "ida/c0d9p",0x4890 },
  162. { "ida/c0d10p",0x48A0 },
  163. { "ida/c0d11p",0x48B0 },
  164. { "ida/c0d12p",0x48C0 },
  165. { "ida/c0d13p",0x48D0 },
  166. { "ida/c0d14p",0x48E0 },
  167. { "ida/c0d15p",0x48F0 },
  168. { "ida/c1d0p",0x4900 },
  169. { "ida/c2d0p",0x4A00 },
  170. { "ida/c3d0p",0x4B00 },
  171. { "ida/c4d0p",0x4C00 },
  172. { "ida/c5d0p",0x4D00 },
  173. { "ida/c6d0p",0x4E00 },
  174. { "ida/c7d0p",0x4F00 }, 
  175. #endif
  176. #if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
  177. { "cciss/c0d0p",0x6800 },
  178. { "cciss/c0d1p",0x6810 },
  179. { "cciss/c0d2p",0x6820 },
  180. { "cciss/c0d3p",0x6830 },
  181. { "cciss/c0d4p",0x6840 },
  182. { "cciss/c0d5p",0x6850 },
  183. { "cciss/c0d6p",0x6860 },
  184. { "cciss/c0d7p",0x6870 },
  185. { "cciss/c0d8p",0x6880 },
  186. { "cciss/c0d9p",0x6890 },
  187. { "cciss/c0d10p",0x68A0 },
  188. { "cciss/c0d11p",0x68B0 },
  189. { "cciss/c0d12p",0x68C0 },
  190. { "cciss/c0d13p",0x68D0 },
  191. { "cciss/c0d14p",0x68E0 },
  192. { "cciss/c0d15p",0x68F0 },
  193. { "cciss/c1d0p",0x6900 },
  194. { "cciss/c2d0p",0x6A00 },
  195. { "cciss/c3d0p",0x6B00 },
  196. { "cciss/c4d0p",0x6C00 },
  197. { "cciss/c5d0p",0x6D00 },
  198. { "cciss/c6d0p",0x6E00 },
  199. { "cciss/c7d0p",0x6F00 },
  200. #endif
  201. { "ataraid/d0p",0x7200 },
  202. { "ataraid/d1p",0x7210 },
  203. { "ataraid/d2p",0x7220 },
  204. { "ataraid/d3p",0x7230 },
  205. { "ataraid/d4p",0x7240 },
  206. { "ataraid/d5p",0x7250 },
  207. { "ataraid/d6p",0x7260 },
  208. { "ataraid/d7p",0x7270 },
  209. { "ataraid/d8p",0x7280 },
  210. { "ataraid/d9p",0x7290 },
  211. { "ataraid/d10p",0x72A0 },
  212. { "ataraid/d11p",0x72B0 },
  213. { "ataraid/d12p",0x72C0 },
  214. { "ataraid/d13p",0x72D0 },
  215. { "ataraid/d14p",0x72E0 },
  216. { "ataraid/d15p",0x72F0 },
  217. { "nftla", 0x5d00 },
  218. { "nftlb", 0x5d10 },
  219. { "nftlc", 0x5d20 },
  220. { "nftld", 0x5d30 },
  221. { "ftla", 0x2c00 },
  222. { "ftlb", 0x2c08 },
  223. { "ftlc", 0x2c10 },
  224. { "ftld", 0x2c18 },
  225. { "mtdblock", 0x1f00 },
  226. { NULL, 0 }
  227. };
  228. kdev_t __init name_to_kdev_t(char *line)
  229. {
  230. int base = 0, offs;
  231. char *end;
  232. if (strncmp(line,"/dev/",5) == 0) {
  233. struct dev_name_struct *dev = root_dev_names;
  234. line += 5;
  235. do {
  236. int len = strlen(dev->name);
  237. if (strncmp(line,dev->name,len) == 0) {
  238. line += len;
  239. base = dev->num;
  240. break;
  241. }
  242. dev++;
  243. } while (dev->name);
  244. }
  245. offs = simple_strtoul(line, &end, base?10:16);
  246. if (*end)
  247. offs = 0;
  248. return to_kdev_t(base + offs);
  249. }
  250. static int __init root_dev_setup(char *line)
  251. {
  252. int i;
  253. char ch;
  254. ROOT_DEV = name_to_kdev_t(line);
  255. memset (root_device_name, 0, sizeof root_device_name);
  256. if (strncmp (line, "/dev/", 5) == 0) line += 5;
  257. for (i = 0; i < sizeof root_device_name - 1; ++i)
  258. {
  259.     ch = line[i];
  260.     if ( isspace (ch) || (ch == ',') || (ch == '') ) break;
  261.     root_device_name[i] = ch;
  262. }
  263. return 1;
  264. }
  265. __setup("root=", root_dev_setup);
  266. static char * __initdata root_mount_data;
  267. static int __init root_data_setup(char *str)
  268. {
  269. root_mount_data = str;
  270. return 1;
  271. }
  272. static char * __initdata root_fs_names;
  273. static int __init fs_names_setup(char *str)
  274. {
  275. root_fs_names = str;
  276. return 1;
  277. }
  278. __setup("rootflags=", root_data_setup);
  279. __setup("rootfstype=", fs_names_setup);
  280. static void __init get_fs_names(char *page)
  281. {
  282. char *s = page;
  283. if (root_fs_names) {
  284. strcpy(page, root_fs_names);
  285. while (*s++) {
  286. if (s[-1] == ',')
  287. s[-1] = '';
  288. }
  289. } else {
  290. int len = get_filesystem_list(page);
  291. char *p, *next;
  292. page[len] = '';
  293. for (p = page-1; p; p = next) {
  294. next = strchr(++p, 'n');
  295. if (*p++ != 't')
  296. continue;
  297. while ((*s++ = *p++) != 'n')
  298. ;
  299. s[-1] = '';
  300. }
  301. }
  302. *s = '';
  303. }
  304. static void __init mount_block_root(char *name, int flags)
  305. {
  306. char *fs_names = __getname();
  307. char *p;
  308. get_fs_names(fs_names);
  309. retry:
  310. for (p = fs_names; *p; p += strlen(p)+1) {
  311. int err = sys_mount(name, "/root", p, flags, root_mount_data);
  312. switch (err) {
  313. case 0:
  314. goto out;
  315. case -EACCES:
  316. flags |= MS_RDONLY;
  317. goto retry;
  318. case -EINVAL:
  319. continue;
  320. }
  321.         /*
  322.  * Allow the user to distinguish between failed open
  323.  * and bad superblock on root device.
  324.  */
  325. printk ("VFS: Cannot open root device "%s" or %sn",
  326. root_device_name, kdevname (ROOT_DEV));
  327. printk ("Please append a correct "root=" boot optionn");
  328. panic("VFS: Unable to mount root fs on %s",
  329. kdevname(ROOT_DEV));
  330. }
  331. panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
  332. out:
  333. putname(fs_names);
  334. sys_chdir("/root");
  335. ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
  336. printk("VFS: Mounted root (%s filesystem)%s.n",
  337. current->fs->pwdmnt->mnt_sb->s_type->name,
  338. (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
  339. }
  340.  
  341. #ifdef CONFIG_ROOT_NFS
  342. static int __init mount_nfs_root(void)
  343. {
  344. void *data = nfs_root_data();
  345. if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
  346. return 1;
  347. return 0;
  348. }
  349. #endif
  350. static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
  351. {
  352. void *handle;
  353. char path[64];
  354. int n;
  355. sys_unlink(name);
  356. if (!do_devfs)
  357. return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));
  358. handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
  359. MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
  360. if (!handle)
  361. return -1;
  362. n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
  363. if (n < 0)
  364. return -1;
  365. return sys_symlink(path + n + 5, name);
  366. }
  367. #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
  368. static void __init change_floppy(char *fmt, ...)
  369. {
  370. struct termios termios;
  371. char buf[80];
  372. char c;
  373. int fd;
  374. va_list args;
  375. va_start(args, fmt);
  376. vsprintf(buf, fmt, args);
  377. va_end(args);
  378. fd = open("/dev/root", O_RDWR | O_NDELAY, 0);
  379. if (fd >= 0) {
  380. sys_ioctl(fd, FDEJECT, 0);
  381. close(fd);
  382. }
  383. printk(KERN_NOTICE "VFS: Insert %s and press ENTERn", buf);
  384. fd = open("/dev/console", O_RDWR, 0);
  385. if (fd >= 0) {
  386. sys_ioctl(fd, TCGETS, (long)&termios);
  387. termios.c_lflag &= ~ICANON;
  388. sys_ioctl(fd, TCSETSF, (long)&termios);
  389. read(fd, &c, 1);
  390. termios.c_lflag |= ICANON;
  391. sys_ioctl(fd, TCSETSF, (long)&termios);
  392. close(fd);
  393. }
  394. }
  395. #endif
  396. #ifdef CONFIG_BLK_DEV_RAM
  397. int __initdata rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */
  398. static int __init prompt_ramdisk(char *str)
  399. {
  400. rd_prompt = simple_strtol(str,NULL,0) & 1;
  401. return 1;
  402. }
  403. __setup("prompt_ramdisk=", prompt_ramdisk);
  404. int __initdata rd_image_start; /* starting block # of image */
  405. static int __init ramdisk_start_setup(char *str)
  406. {
  407. rd_image_start = simple_strtol(str,NULL,0);
  408. return 1;
  409. }
  410. __setup("ramdisk_start=", ramdisk_start_setup);
  411. static int __init crd_load(int in_fd, int out_fd);
  412. /*
  413.  * This routine tries to find a RAM disk image to load, and returns the
  414.  * number of blocks to read for a non-compressed image, 0 if the image
  415.  * is a compressed image, and -1 if an image with the right magic
  416.  * numbers could not be found.
  417.  *
  418.  * We currently check for the following magic numbers:
  419.  *  minix
  420.  *  ext2
  421.  * romfs
  422.  *  gzip
  423.  */
  424. static int __init 
  425. identify_ramdisk_image(int fd, int start_block)
  426. {
  427. const int size = 512;
  428. struct minix_super_block *minixsb;
  429. struct ext2_super_block *ext2sb;
  430. struct romfs_super_block *romfsb;
  431. int nblocks = -1;
  432. unsigned char *buf;
  433. buf = kmalloc(size, GFP_KERNEL);
  434. if (buf == 0)
  435. return -1;
  436. minixsb = (struct minix_super_block *) buf;
  437. ext2sb = (struct ext2_super_block *) buf;
  438. romfsb = (struct romfs_super_block *) buf;
  439. memset(buf, 0xe5, size);
  440. /*
  441.  * Read block 0 to test for gzipped kernel
  442.  */
  443. lseek(fd, start_block * BLOCK_SIZE, 0);
  444. read(fd, buf, size);
  445. /*
  446.  * If it matches the gzip magic numbers, return -1
  447.  */
  448. if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
  449. printk(KERN_NOTICE
  450.        "RAMDISK: Compressed image found at block %dn",
  451.        start_block);
  452. nblocks = 0;
  453. goto done;
  454. }
  455. /* romfs is at block zero too */
  456. if (romfsb->word0 == ROMSB_WORD0 &&
  457.     romfsb->word1 == ROMSB_WORD1) {
  458. printk(KERN_NOTICE
  459.        "RAMDISK: romfs filesystem found at block %dn",
  460.        start_block);
  461. nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
  462. goto done;
  463. }
  464. /*
  465.  * Read block 1 to test for minix and ext2 superblock
  466.  */
  467. lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
  468. read(fd, buf, size);
  469. /* Try minix */
  470. if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
  471.     minixsb->s_magic == MINIX_SUPER_MAGIC2) {
  472. printk(KERN_NOTICE
  473.        "RAMDISK: Minix filesystem found at block %dn",
  474.        start_block);
  475. nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
  476. goto done;
  477. }
  478. /* Try ext2 */
  479. if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
  480. printk(KERN_NOTICE
  481.        "RAMDISK: ext2 filesystem found at block %dn",
  482.        start_block);
  483. nblocks = le32_to_cpu(ext2sb->s_blocks_count);
  484. goto done;
  485. }
  486. printk(KERN_NOTICE
  487.        "RAMDISK: Couldn't find valid RAM disk image starting at %d.n",
  488.        start_block);
  489. done:
  490. lseek(fd, start_block * BLOCK_SIZE, 0);
  491. kfree(buf);
  492. return nblocks;
  493. }
  494. #endif
  495. static int __init rd_load_image(char *from)
  496. {
  497. int res = 0;
  498. #ifdef CONFIG_BLK_DEV_RAM
  499. int in_fd, out_fd;
  500. unsigned long rd_blocks, devblocks;
  501. int nblocks, i;
  502. char *buf;
  503. unsigned short rotate = 0;
  504. #if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
  505. char rotator[4] = { '|' , '/' , '-' , '\' };
  506. #endif
  507. out_fd = open("/dev/ram", O_RDWR, 0);
  508. if (out_fd < 0)
  509. goto out;
  510. in_fd = open(from, O_RDONLY, 0);
  511. if (in_fd < 0)
  512. goto noclose_input;
  513. nblocks = identify_ramdisk_image(in_fd, rd_image_start);
  514. if (nblocks < 0)
  515. goto done;
  516. if (nblocks == 0) {
  517. #ifdef BUILD_CRAMDISK
  518. if (crd_load(in_fd, out_fd) == 0)
  519. goto successful_load;
  520. #else
  521. printk(KERN_NOTICE
  522.        "RAMDISK: Kernel does not support compressed "
  523.        "RAM disk imagesn");
  524. #endif
  525. goto done;
  526. }
  527. /*
  528.  * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
  529.  * rd_load_image will work only with filesystem BLOCK_SIZE wide!
  530.  * So make sure to use 1k blocksize while generating ext2fs
  531.  * ramdisk-images.
  532.  */
  533. if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
  534. rd_blocks = 0;
  535. else
  536. rd_blocks >>= 1;
  537. if (nblocks > rd_blocks) {
  538. printk("RAMDISK: image too big! (%d/%d blocks)n",
  539.        nblocks, rd_blocks);
  540. goto done;
  541. }
  542. /*
  543.  * OK, time to copy in the data
  544.  */
  545. buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
  546. if (buf == 0) {
  547. printk(KERN_ERR "RAMDISK: could not allocate buffern");
  548. goto done;
  549. }
  550. if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
  551. devblocks = 0;
  552. else
  553. devblocks >>= 1;
  554. if (strcmp(from, "/dev/initrd") == 0)
  555. devblocks = nblocks;
  556. if (devblocks == 0) {
  557. printk(KERN_ERR "RAMDISK: could not determine device sizen");
  558. goto done;
  559. }
  560. printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ", 
  561. nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
  562. for (i=0; i < nblocks; i++) {
  563. if (i && (i % devblocks == 0)) {
  564. printk("done disk #%d.n", i/devblocks);
  565. rotate = 0;
  566. if (close(in_fd)) {
  567. printk("Error closing the disk.n");
  568. goto noclose_input;
  569. }
  570. change_floppy("disk #%d", i/devblocks+1);
  571. in_fd = open(from, O_RDONLY, 0);
  572. if (in_fd < 0)  {
  573. printk("Error opening disk.n");
  574. goto noclose_input;
  575. }
  576. printk("Loading disk #%d... ", i/devblocks+1);
  577. }
  578. read(in_fd, buf, BLOCK_SIZE);
  579. write(out_fd, buf, BLOCK_SIZE);
  580. #if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
  581. if (!(i % 16)) {
  582. printk("%cb", rotator[rotate & 0x3]);
  583. rotate++;
  584. }
  585. #endif
  586. }
  587. printk("done.n");
  588. kfree(buf);
  589. successful_load:
  590. res = 1;
  591. done:
  592. close(in_fd);
  593. noclose_input:
  594. close(out_fd);
  595. out:
  596. sys_unlink("/dev/ram");
  597. #endif
  598. return res;
  599. }
  600. static int __init rd_load_disk(int n)
  601. {
  602. #ifdef CONFIG_BLK_DEV_RAM
  603. if (rd_prompt)
  604. change_floppy("root floppy disk to be loaded into RAM disk");
  605. create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
  606. #endif
  607. return rd_load_image("/dev/root");
  608. }
  609. #ifdef CONFIG_DEVFS_FS
  610. static void __init convert_name(char *prefix, char *name, char *p, int part)
  611. {
  612. int host, bus, target, lun;
  613. char dest[64];
  614. char src[64];
  615. char *base = p - 1;
  616. /*  Decode "c#b#t#u#"  */
  617. if (*p++ != 'c')
  618. return;
  619. host = simple_strtol(p, &p, 10);
  620. if (*p++ != 'b')
  621. return;
  622. bus = simple_strtol(p, &p, 10);
  623. if (*p++ != 't')
  624. return;
  625. target = simple_strtol(p, &p, 10);
  626. if (*p++ != 'u')
  627. return;
  628. lun = simple_strtol(p, &p, 10);
  629. if (!part)
  630. sprintf(dest, "%s/host%d/bus%d/target%d/lun%d",
  631. prefix, host, bus, target, lun);
  632. else if (*p++ == 'p')
  633. sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/part%s",
  634. prefix, host, bus, target, lun, p);
  635. else
  636. sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/disc",
  637. prefix, host, bus, target, lun);
  638. *base = '';
  639. sprintf(src, "/dev/%s", name);
  640. sys_mkdir(src, 0755);
  641. *base = '/';
  642. sprintf(src, "/dev/%s", name);
  643. sys_symlink(dest, src);
  644. }
  645. static void __init devfs_make_root(char *name)
  646. {
  647. if (!strncmp(name, "sd/", 3))
  648. convert_name("../scsi", name, name+3, 1);
  649. else if (!strncmp(name, "sr/", 3))
  650. convert_name("../scsi", name, name+3, 0);
  651. else if (!strncmp(name, "ide/hd/", 7))
  652. convert_name("..", name, name + 7, 1);
  653. else if (!strncmp(name, "ide/cd/", 7))
  654. convert_name("..", name, name + 7, 0);
  655. }
  656. #else
  657. static void __init devfs_make_root(char *name)
  658. {
  659. }
  660. #endif
  661. static void __init mount_root(void)
  662. {
  663. #ifdef CONFIG_ROOT_NFS
  664. if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
  665. if (mount_nfs_root()) {
  666. sys_chdir("/root");
  667. ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
  668. printk("VFS: Mounted root (nfs filesystem).n");
  669. return;
  670. }
  671. printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.n");
  672. ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
  673. }
  674. #endif
  675. devfs_make_root(root_device_name);
  676. create_dev("/dev/root", ROOT_DEV, root_device_name);
  677. #ifdef CONFIG_BLK_DEV_FD
  678. if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
  679. /* rd_doload is 2 for a dual initrd/ramload setup */
  680. if (rd_doload==2) {
  681. if (rd_load_disk(1)) {
  682. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1);
  683. create_dev("/dev/root", ROOT_DEV, NULL);
  684. }
  685. } else
  686. change_floppy("root floppy");
  687. }
  688. #endif
  689. mount_block_root("/dev/root", root_mountflags);
  690. }
  691. #ifdef CONFIG_BLK_DEV_INITRD
  692. static int old_fd, root_fd;
  693. static int do_linuxrc(void * shell)
  694. {
  695. static char *argv[] = { "linuxrc", NULL, };
  696. extern char * envp_init[];
  697. close(old_fd);
  698. close(root_fd);
  699. close(0);
  700. close(1);
  701. close(2);
  702. setsid();
  703. (void) open("/dev/console",O_RDWR,0);
  704. (void) dup(0);
  705. (void) dup(0);
  706. return execve(shell, argv, envp_init);
  707. }
  708. #endif
  709. static void __init handle_initrd(void)
  710. {
  711. #ifdef CONFIG_BLK_DEV_INITRD
  712. int ram0 = kdev_t_to_nr(MKDEV(RAMDISK_MAJOR,0));
  713. int error;
  714. int i, pid;
  715. create_dev("/dev/root.old", ram0, NULL);
  716. /* mount initrd on rootfs' /root */
  717. mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
  718. sys_mkdir("/old", 0700);
  719. root_fd = open("/", 0, 0);
  720. old_fd = open("/old", 0, 0);
  721. /* move initrd over / and chdir/chroot in initrd root */
  722. sys_chdir("/root");
  723. sys_mount(".", "/", NULL, MS_MOVE, NULL);
  724. sys_chroot(".");
  725. mount_devfs_fs ();
  726. pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
  727. if (pid > 0) {
  728. while (pid != wait(&i))
  729. yield();
  730. }
  731. /* move initrd to rootfs' /old */
  732. sys_fchdir(old_fd);
  733. sys_mount("/", ".", NULL, MS_MOVE, NULL);
  734. /* switch root and cwd back to / of rootfs */
  735. sys_fchdir(root_fd);
  736. sys_chroot(".");
  737. sys_umount("/old/dev", 0);
  738. if (real_root_dev == ram0) {
  739. sys_chdir("/old");
  740. return;
  741. }
  742. ROOT_DEV = real_root_dev;
  743. mount_root();
  744. printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
  745. error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
  746. if (!error)
  747. printk("okayn");
  748. else {
  749. int fd = open("/dev/root.old", O_RDWR, 0);
  750. printk("failedn");
  751. printk(KERN_NOTICE "Unmounting old rootn");
  752. sys_umount("/old", MNT_DETACH);
  753. printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
  754. if (fd < 0) {
  755. error = fd;
  756. } else {
  757. error = sys_ioctl(fd, BLKFLSBUF, 0);
  758. close(fd);
  759. }
  760. printk(!error ? "okayn" : "failedn");
  761. }
  762. #endif
  763. }
  764. static int __init initrd_load(void)
  765. {
  766. #ifdef CONFIG_BLK_DEV_INITRD
  767. create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
  768. create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
  769. #endif
  770. return rd_load_image("/dev/initrd");
  771. }
  772. /*
  773.  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  774.  */
  775. void prepare_namespace(void)
  776. {
  777. int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
  778. #ifdef CONFIG_ALL_PPC
  779. extern void arch_discover_root(void);
  780. arch_discover_root();
  781. #endif /* CONFIG_ALL_PPC */
  782. #ifdef CONFIG_BLK_DEV_INITRD
  783. if (!initrd_start)
  784. mount_initrd = 0;
  785. real_root_dev = ROOT_DEV;
  786. #endif
  787. sys_mkdir("/dev", 0700);
  788. sys_mkdir("/root", 0700);
  789. sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(TTYAUX_MAJOR, 1));
  790. #ifdef CONFIG_DEVFS_FS
  791. sys_mount("devfs", "/dev", "devfs", 0, NULL);
  792. do_devfs = 1;
  793. #endif
  794. create_dev("/dev/root", ROOT_DEV, NULL);
  795. if (mount_initrd) {
  796. if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) {
  797. handle_initrd();
  798. goto out;
  799. }
  800. } else if (is_floppy && rd_doload && rd_load_disk(0))
  801. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  802. mount_root();
  803. out:
  804. sys_umount("/dev", 0);
  805. sys_mount(".", "/", NULL, MS_MOVE, NULL);
  806. sys_chroot(".");
  807. mount_devfs_fs ();
  808. }
  809. #if defined(BUILD_CRAMDISK) && defined(CONFIG_BLK_DEV_RAM)
  810. /*
  811.  * gzip declarations
  812.  */
  813. #define OF(args)  args
  814. #ifndef memzero
  815. #define memzero(s, n)     memset ((s), 0, (n))
  816. #endif
  817. typedef unsigned char  uch;
  818. typedef unsigned short ush;
  819. typedef unsigned long  ulg;
  820. #define INBUFSIZ 4096
  821. #define WSIZE 0x8000    /* window size--must be a power of two, and */
  822. /*  at least 32K for zip's deflate method */
  823. static uch *inbuf;
  824. static uch *window;
  825. static unsigned insize;  /* valid bytes in inbuf */
  826. static unsigned inptr;   /* index of next byte to be processed in inbuf */
  827. static unsigned outcnt;  /* bytes in output buffer */
  828. static int exit_code;
  829. static long bytes_out;
  830. static int crd_infd, crd_outfd;
  831. #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  832. /* Diagnostic functions (stubbed out) */
  833. #define Assert(cond,msg)
  834. #define Trace(x)
  835. #define Tracev(x)
  836. #define Tracevv(x)
  837. #define Tracec(c,x)
  838. #define Tracecv(c,x)
  839. #define STATIC static
  840. static int  fill_inbuf(void);
  841. static void flush_window(void);
  842. static void *malloc(int size);
  843. static void free(void *where);
  844. static void error(char *m);
  845. static void gzip_mark(void **);
  846. static void gzip_release(void **);
  847. #include "../lib/inflate.c"
  848. static void __init *malloc(int size)
  849. {
  850. return kmalloc(size, GFP_KERNEL);
  851. }
  852. static void __init free(void *where)
  853. {
  854. kfree(where);
  855. }
  856. static void __init gzip_mark(void **ptr)
  857. {
  858. }
  859. static void __init gzip_release(void **ptr)
  860. {
  861. }
  862. /* ===========================================================================
  863.  * Fill the input buffer. This is called only when the buffer is empty
  864.  * and at least one byte is really needed.
  865.  */
  866. static int __init fill_inbuf(void)
  867. {
  868. if (exit_code) return -1;
  869. insize = read(crd_infd, inbuf, INBUFSIZ);
  870. if (insize == 0) return -1;
  871. inptr = 1;
  872. return inbuf[0];
  873. }
  874. /* ===========================================================================
  875.  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  876.  * (Used for the decompressed data only.)
  877.  */
  878. static void __init flush_window(void)
  879. {
  880.     ulg c = crc;         /* temporary variable */
  881.     unsigned n;
  882.     uch *in, ch;
  883.     
  884.     write(crd_outfd, window, outcnt);
  885.     in = window;
  886.     for (n = 0; n < outcnt; n++) {
  887.     ch = *in++;
  888.     c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
  889.     }
  890.     crc = c;
  891.     bytes_out += (ulg)outcnt;
  892.     outcnt = 0;
  893. }
  894. static void __init error(char *x)
  895. {
  896. printk(KERN_ERR "%s", x);
  897. exit_code = 1;
  898. }
  899. static int __init crd_load(int in_fd, int out_fd)
  900. {
  901. int result;
  902. insize = 0; /* valid bytes in inbuf */
  903. inptr = 0; /* index of next byte to be processed in inbuf */
  904. outcnt = 0; /* bytes in output buffer */
  905. exit_code = 0;
  906. bytes_out = 0;
  907. crc = (ulg)0xffffffffL; /* shift register contents */
  908. crd_infd = in_fd;
  909. crd_outfd = out_fd;
  910. inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
  911. if (inbuf == 0) {
  912. printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffern");
  913. return -1;
  914. }
  915. window = kmalloc(WSIZE, GFP_KERNEL);
  916. if (window == 0) {
  917. printk(KERN_ERR "RAMDISK: Couldn't allocate gzip windown");
  918. kfree(inbuf);
  919. return -1;
  920. }
  921. makecrc();
  922. result = gunzip();
  923. kfree(inbuf);
  924. kfree(window);
  925. return result;
  926. }
  927. #endif  /* BUILD_CRAMDISK && CONFIG_BLK_DEV_RAM */