The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/init/do_mounts.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: cf756bbadaf0c167a327c56b6dd0c299


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.