aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /init
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig463
-rw-r--r--init/Makefile28
-rw-r--r--init/calibrate.c79
-rw-r--r--init/do_mounts.c430
-rw-r--r--init/do_mounts.h92
-rw-r--r--init/do_mounts_devfs.c137
-rw-r--r--init/do_mounts_initrd.c121
-rw-r--r--init/do_mounts_md.c290
-rw-r--r--init/do_mounts_rd.c429
-rw-r--r--init/initramfs.c500
-rw-r--r--init/main.c713
-rw-r--r--init/version.c33
12 files changed, 3315 insertions, 0 deletions
diff --git a/init/Kconfig b/init/Kconfig
new file mode 100644
index 00000000000..abe2682a6ca
--- /dev/null
+++ b/init/Kconfig
@@ -0,0 +1,463 @@
1menu "Code maturity level options"
2
3config EXPERIMENTAL
4 bool "Prompt for development and/or incomplete code/drivers"
5 ---help---
6 Some of the various things that Linux supports (such as network
7 drivers, file systems, network protocols, etc.) can be in a state
8 of development where the functionality, stability, or the level of
9 testing is not yet high enough for general use. This is usually
10 known as the "alpha-test" phase among developers. If a feature is
11 currently in alpha-test, then the developers usually discourage
12 uninformed widespread use of this feature by the general public to
13 avoid "Why doesn't this work?" type mail messages. However, active
14 testing and use of these systems is welcomed. Just be aware that it
15 may not meet the normal level of reliability or it may fail to work
16 in some special cases. Detailed bug reports from people familiar
17 with the kernel internals are usually welcomed by the developers
18 (before submitting bug reports, please read the documents
19 <file:README>, <file:MAINTAINERS>, <file:REPORTING-BUGS>,
20 <file:Documentation/BUG-HUNTING>, and
21 <file:Documentation/oops-tracing.txt> in the kernel source).
22
23 This option will also make obsoleted drivers available. These are
24 drivers that have been replaced by something else, and/or are
25 scheduled to be removed in a future kernel release.
26
27 Unless you intend to help test and develop a feature or driver that
28 falls into this category, or you have a situation that requires
29 using these features, you should probably say N here, which will
30 cause the configurator to present you with fewer choices. If
31 you say Y here, you will be offered the choice of using features or
32 drivers that are currently considered to be in the alpha-test phase.
33
34config CLEAN_COMPILE
35 bool "Select only drivers expected to compile cleanly" if EXPERIMENTAL
36 default y
37 help
38 Select this option if you don't even want to see the option
39 to configure known-broken drivers.
40
41 If unsure, say Y
42
43config BROKEN
44 bool
45 depends on !CLEAN_COMPILE
46 default y
47
48config BROKEN_ON_SMP
49 bool
50 depends on BROKEN || !SMP
51 default y
52
53config LOCK_KERNEL
54 bool
55 depends on SMP || PREEMPT
56 default y
57
58config INIT_ENV_ARG_LIMIT
59 int
60 default 32 if !USERMODE
61 default 128 if USERMODE
62 help
63 This is the value of the two limits on the number of argument and of
64 env.var passed to init from the kernel command line.
65
66endmenu
67
68menu "General setup"
69
70config LOCALVERSION
71 string "Local version - append to kernel release"
72 help
73 Append an extra string to the end of your kernel version.
74 This will show up when you type uname, for example.
75 The string you set here will be appended after the contents of
76 any files with a filename matching localversion* in your
77 object and source tree, in that order. Your total string can
78 be a maximum of 64 characters.
79
80config SWAP
81 bool "Support for paging of anonymous memory (swap)"
82 depends on MMU
83 default y
84 help
85 This option allows you to choose whether you want to have support
86 for socalled swap devices or swap files in your kernel that are
87 used to provide more virtual memory than the actual RAM present
88 in your computer. If unsure say Y.
89
90config SYSVIPC
91 bool "System V IPC"
92 depends on MMU
93 ---help---
94 Inter Process Communication is a suite of library functions and
95 system calls which let processes (running programs) synchronize and
96 exchange information. It is generally considered to be a good thing,
97 and some programs won't run unless you say Y here. In particular, if
98 you want to run the DOS emulator dosemu under Linux (read the
99 DOSEMU-HOWTO, available from <http://www.tldp.org/docs.html#howto>),
100 you'll need to say Y here.
101
102 You can find documentation about IPC with "info ipc" and also in
103 section 6.4 of the Linux Programmer's Guide, available from
104 <http://www.tldp.org/guides.html>.
105
106config POSIX_MQUEUE
107 bool "POSIX Message Queues"
108 depends on NET && EXPERIMENTAL
109 ---help---
110 POSIX variant of message queues is a part of IPC. In POSIX message
111 queues every message has a priority which decides about succession
112 of receiving it by a process. If you want to compile and run
113 programs written e.g. for Solaris with use of its POSIX message
114 queues (functions mq_*) say Y here. To use this feature you will
115 also need mqueue library, available from
116 <http://www.mat.uni.torun.pl/~wrona/posix_ipc/>
117
118 POSIX message queues are visible as a filesystem called 'mqueue'
119 and can be mounted somewhere if you want to do filesystem
120 operations on message queues.
121
122 If unsure, say Y.
123
124config BSD_PROCESS_ACCT
125 bool "BSD Process Accounting"
126 help
127 If you say Y here, a user level program will be able to instruct the
128 kernel (via a special system call) to write process accounting
129 information to a file: whenever a process exits, information about
130 that process will be appended to the file by the kernel. The
131 information includes things such as creation time, owning user,
132 command name, memory usage, controlling terminal etc. (the complete
133 list is in the struct acct in <file:include/linux/acct.h>). It is
134 up to the user level program to do useful things with this
135 information. This is generally a good idea, so say Y.
136
137config BSD_PROCESS_ACCT_V3
138 bool "BSD Process Accounting version 3 file format"
139 depends on BSD_PROCESS_ACCT
140 default n
141 help
142 If you say Y here, the process accounting information is written
143 in a new file format that also logs the process IDs of each
144 process and it's parent. Note that this file format is incompatible
145 with previous v0/v1/v2 file formats, so you will need updated tools
146 for processing it. A preliminary version of these tools is available
147 at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>.
148
149config SYSCTL
150 bool "Sysctl support"
151 ---help---
152 The sysctl interface provides a means of dynamically changing
153 certain kernel parameters and variables on the fly without requiring
154 a recompile of the kernel or reboot of the system. The primary
155 interface consists of a system call, but if you say Y to "/proc
156 file system support", a tree of modifiable sysctl entries will be
157 generated beneath the /proc/sys directory. They are explained in the
158 files in <file:Documentation/sysctl/>. Note that enabling this
159 option will enlarge the kernel by at least 8 KB.
160
161 As it is generally a good thing, you should say Y here unless
162 building a kernel for install/rescue disks or your system is very
163 limited in memory.
164
165config AUDIT
166 bool "Auditing support"
167 default y if SECURITY_SELINUX
168 help
169 Enable auditing infrastructure that can be used with another
170 kernel subsystem, such as SELinux (which requires this for
171 logging of avc messages output). Does not do system-call
172 auditing without CONFIG_AUDITSYSCALL.
173
174config AUDITSYSCALL
175 bool "Enable system-call auditing support"
176 depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64)
177 default y if SECURITY_SELINUX
178 help
179 Enable low-overhead system-call auditing infrastructure that
180 can be used independently or with another kernel subsystem,
181 such as SELinux.
182
183config HOTPLUG
184 bool "Support for hot-pluggable devices" if !ARCH_S390
185 default ARCH_S390
186 help
187 This option is provided for the case where no in-kernel-tree
188 modules require HOTPLUG functionality, but a module built
189 outside the kernel tree does. Such modules require Y here.
190
191config KOBJECT_UEVENT
192 bool "Kernel Userspace Events"
193 depends on NET
194 default y
195 help
196 This option enables the kernel userspace event layer, which is a
197 simple mechanism for kernel-to-user communication over a netlink
198 socket.
199 The goal of the kernel userspace events layer is to provide a simple
200 and efficient events system, that notifies userspace about kobject
201 state changes. This will enable applications to just listen for
202 events instead of polling system devices and files.
203 Hotplug events (kobject addition and removal) are also available on
204 the netlink socket in addition to the execution of /sbin/hotplug if
205 CONFIG_HOTPLUG is enabled.
206
207 Say Y, unless you are building a system requiring minimal memory
208 consumption.
209
210config IKCONFIG
211 bool "Kernel .config support"
212 ---help---
213 This option enables the complete Linux kernel ".config" file
214 contents to be saved in the kernel. It provides documentation
215 of which kernel options are used in a running kernel or in an
216 on-disk kernel. This information can be extracted from the kernel
217 image file with the script scripts/extract-ikconfig and used as
218 input to rebuild the current kernel or to build another kernel.
219 It can also be extracted from a running kernel by reading
220 /proc/config.gz if enabled (below).
221
222config IKCONFIG_PROC
223 bool "Enable access to .config through /proc/config.gz"
224 depends on IKCONFIG && PROC_FS
225 ---help---
226 This option enables access to the kernel configuration file
227 through /proc/config.gz.
228
229config CPUSETS
230 bool "Cpuset support"
231 depends on SMP
232 help
233 This options will let you create and manage CPUSET's which
234 allow dynamically partitioning a system into sets of CPUs and
235 Memory Nodes and assigning tasks to run only within those sets.
236 This is primarily useful on large SMP or NUMA systems.
237
238 Say N if unsure.
239
240menuconfig EMBEDDED
241 bool "Configure standard kernel features (for small systems)"
242 help
243 This option allows certain base kernel options and settings
244 to be disabled or tweaked. This is for specialized
245 environments which can tolerate a "non-standard" kernel.
246 Only use this if you really know what you are doing.
247
248config KALLSYMS
249 bool "Load all symbols for debugging/kksymoops" if EMBEDDED
250 default y
251 help
252 Say Y here to let the kernel print out symbolic crash information and
253 symbolic stack backtraces. This increases the size of the kernel
254 somewhat, as all symbols have to be loaded into the kernel image.
255
256config KALLSYMS_ALL
257 bool "Include all symbols in kallsyms"
258 depends on DEBUG_KERNEL && KALLSYMS
259 help
260 Normally kallsyms only contains the symbols of functions, for nicer
261 OOPS messages. Some debuggers can use kallsyms for other
262 symbols too: say Y here to include all symbols, and you
263 don't care about adding 300k to the size of your kernel.
264
265 Say N.
266
267config KALLSYMS_EXTRA_PASS
268 bool "Do an extra kallsyms pass"
269 depends on KALLSYMS
270 help
271 If kallsyms is not working correctly, the build will fail with
272 inconsistent kallsyms data. If that occurs, log a bug report and
273 turn on KALLSYMS_EXTRA_PASS which should result in a stable build.
274 Always say N here unless you find a bug in kallsyms, which must be
275 reported. KALLSYMS_EXTRA_PASS is only a temporary workaround while
276 you wait for kallsyms to be fixed.
277
278config BASE_FULL
279 default y
280 bool "Enable full-sized data structures for core" if EMBEDDED
281 help
282 Disabling this option reduces the size of miscellaneous core
283 kernel data structures. This saves memory on small machines,
284 but may reduce performance.
285
286config FUTEX
287 bool "Enable futex support" if EMBEDDED
288 default y
289 help
290 Disabling this option will cause the kernel to be built without
291 support for "fast userspace mutexes". The resulting kernel may not
292 run glibc-based applications correctly.
293
294config EPOLL
295 bool "Enable eventpoll support" if EMBEDDED
296 default y
297 help
298 Disabling this option will cause the kernel to be built without
299 support for epoll family of system calls.
300
301config CC_OPTIMIZE_FOR_SIZE
302 bool "Optimize for size" if EMBEDDED
303 default y if ARM || H8300
304 help
305 Enabling this option will pass "-Os" instead of "-O2" to gcc
306 resulting in a smaller kernel.
307
308 WARNING: some versions of gcc may generate incorrect code with this
309 option. If problems are observed, a gcc upgrade may be needed.
310
311 If unsure, say N.
312
313config SHMEM
314 bool "Use full shmem filesystem" if EMBEDDED
315 default y
316 depends on MMU
317 help
318 The shmem is an internal filesystem used to manage shared memory.
319 It is backed by swap and manages resource limits. It is also exported
320 to userspace as tmpfs if TMPFS is enabled. Disabling this
321 option replaces shmem and tmpfs with the much simpler ramfs code,
322 which may be appropriate on small systems without swap.
323
324config CC_ALIGN_FUNCTIONS
325 int "Function alignment" if EMBEDDED
326 default 0
327 help
328 Align the start of functions to the next power-of-two greater than n,
329 skipping up to n bytes. For instance, 32 aligns functions
330 to the next 32-byte boundary, but 24 would align to the next
331 32-byte boundary only if this can be done by skipping 23 bytes or less.
332 Zero means use compiler's default.
333
334config CC_ALIGN_LABELS
335 int "Label alignment" if EMBEDDED
336 default 0
337 help
338 Align all branch targets to a power-of-two boundary, skipping
339 up to n bytes like ALIGN_FUNCTIONS. This option can easily
340 make code slower, because it must insert dummy operations for
341 when the branch target is reached in the usual flow of the code.
342 Zero means use compiler's default.
343
344config CC_ALIGN_LOOPS
345 int "Loop alignment" if EMBEDDED
346 default 0
347 help
348 Align loops to a power-of-two boundary, skipping up to n bytes.
349 Zero means use compiler's default.
350
351config CC_ALIGN_JUMPS
352 int "Jump alignment" if EMBEDDED
353 default 0
354 help
355 Align branch targets to a power-of-two boundary, for branch
356 targets where the targets can only be reached by jumping,
357 skipping up to n bytes like ALIGN_FUNCTIONS. In this case,
358 no dummy operations need be executed.
359 Zero means use compiler's default.
360
361endmenu # General setup
362
363config TINY_SHMEM
364 default !SHMEM
365 bool
366
367config BASE_SMALL
368 int
369 default 0 if BASE_FULL
370 default 1 if !BASE_FULL
371
372menu "Loadable module support"
373
374config MODULES
375 bool "Enable loadable module support"
376 help
377 Kernel modules are small pieces of compiled code which can
378 be inserted in the running kernel, rather than being
379 permanently built into the kernel. You use the "modprobe"
380 tool to add (and sometimes remove) them. If you say Y here,
381 many parts of the kernel can be built as modules (by
382 answering M instead of Y where indicated): this is most
383 useful for infrequently used options which are not required
384 for booting. For more information, see the man pages for
385 modprobe, lsmod, modinfo, insmod and rmmod.
386
387 If you say Y here, you will need to run "make
388 modules_install" to put the modules under /lib/modules/
389 where modprobe can find them (you may need to be root to do
390 this).
391
392 If unsure, say Y.
393
394config MODULE_UNLOAD
395 bool "Module unloading"
396 depends on MODULES
397 help
398 Without this option you will not be able to unload any
399 modules (note that some modules may not be unloadable
400 anyway), which makes your kernel slightly smaller and
401 simpler. If unsure, say Y.
402
403config MODULE_FORCE_UNLOAD
404 bool "Forced module unloading"
405 depends on MODULE_UNLOAD && EXPERIMENTAL
406 help
407 This option allows you to force a module to unload, even if the
408 kernel believes it is unsafe: the kernel will remove the module
409 without waiting for anyone to stop using it (using the -f option to
410 rmmod). This is mainly for kernel developers and desperate users.
411 If unsure, say N.
412
413config OBSOLETE_MODPARM
414 bool
415 default y
416 depends on MODULES
417 help
418 You need this option to use module parameters on modules which
419 have not been converted to the new module parameter system yet.
420 If unsure, say Y.
421
422config MODVERSIONS
423 bool "Module versioning support (EXPERIMENTAL)"
424 depends on MODULES && EXPERIMENTAL && !UML
425 help
426 Usually, you have to use modules compiled with your kernel.
427 Saying Y here makes it sometimes possible to use modules
428 compiled for different kernels, by adding enough information
429 to the modules to (hopefully) spot any changes which would
430 make them incompatible with the kernel you are running. If
431 unsure, say N.
432
433config MODULE_SRCVERSION_ALL
434 bool "Source checksum for all modules"
435 depends on MODULES
436 help
437 Modules which contain a MODULE_VERSION get an extra "srcversion"
438 field inserted into their modinfo section, which contains a
439 sum of the source files which made it. This helps maintainers
440 see exactly which source was used to build a module (since
441 others sometimes change the module source without updating
442 the version). With this option, such a "srcversion" field
443 will be created for all modules. If unsure, say N.
444
445config KMOD
446 bool "Automatic kernel module loading"
447 depends on MODULES
448 help
449 Normally when you have selected some parts of the kernel to
450 be created as kernel modules, you must load them (using the
451 "modprobe" command) before you can use them. If you say Y
452 here, some parts of the kernel will be able to load modules
453 automatically: when a part of the kernel needs a module, it
454 runs modprobe with the appropriate arguments, thereby
455 loading the module if it is available. If unsure, say Y.
456
457config STOP_MACHINE
458 bool
459 default y
460 depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
461 help
462 Need stop_machine() primitive.
463endmenu
diff --git a/init/Makefile b/init/Makefile
new file mode 100644
index 00000000000..93a53fbdbe7
--- /dev/null
+++ b/init/Makefile
@@ -0,0 +1,28 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := main.o version.o mounts.o initramfs.o
6obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
7
8mounts-y := do_mounts.o
9mounts-$(CONFIG_DEVFS_FS) += do_mounts_devfs.o
10mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
11mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o
12mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
13
14# files to be removed upon make clean
15clean-files := ../include/linux/compile.h
16
17# dependencies on generated files need to be listed explicitly
18
19$(obj)/version.o: include/linux/compile.h
20
21# compile.h changes depending on hostname, generation number, etc,
22# so we regenerate it always.
23# mkcompile_h will make sure to only update the
24# actual file if its content has changed.
25
26include/linux/compile.h: FORCE
27 @echo ' CHK $@'
28 @$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
diff --git a/init/calibrate.c b/init/calibrate.c
new file mode 100644
index 00000000000..c698e04a3db
--- /dev/null
+++ b/init/calibrate.c
@@ -0,0 +1,79 @@
1/* calibrate.c: default delay calibration
2 *
3 * Excised from init/main.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7#include <linux/sched.h>
8#include <linux/delay.h>
9#include <linux/init.h>
10
11static unsigned long preset_lpj;
12static int __init lpj_setup(char *str)
13{
14 preset_lpj = simple_strtoul(str,NULL,0);
15 return 1;
16}
17
18__setup("lpj=", lpj_setup);
19
20/*
21 * This is the number of bits of precision for the loops_per_jiffy. Each
22 * bit takes on average 1.5/HZ seconds. This (like the original) is a little
23 * better than 1%
24 */
25#define LPS_PREC 8
26
27void __devinit calibrate_delay(void)
28{
29 unsigned long ticks, loopbit;
30 int lps_precision = LPS_PREC;
31
32 if (preset_lpj) {
33 loops_per_jiffy = preset_lpj;
34 printk("Calibrating delay loop (skipped)... "
35 "%lu.%02lu BogoMIPS preset\n",
36 loops_per_jiffy/(500000/HZ),
37 (loops_per_jiffy/(5000/HZ)) % 100);
38 } else {
39 loops_per_jiffy = (1<<12);
40
41 printk(KERN_DEBUG "Calibrating delay loop... ");
42 while ((loops_per_jiffy <<= 1) != 0) {
43 /* wait for "start of" clock tick */
44 ticks = jiffies;
45 while (ticks == jiffies)
46 /* nothing */;
47 /* Go .. */
48 ticks = jiffies;
49 __delay(loops_per_jiffy);
50 ticks = jiffies - ticks;
51 if (ticks)
52 break;
53 }
54
55 /*
56 * Do a binary approximation to get loops_per_jiffy set to
57 * equal one clock (up to lps_precision bits)
58 */
59 loops_per_jiffy >>= 1;
60 loopbit = loops_per_jiffy;
61 while (lps_precision-- && (loopbit >>= 1)) {
62 loops_per_jiffy |= loopbit;
63 ticks = jiffies;
64 while (ticks == jiffies)
65 /* nothing */;
66 ticks = jiffies;
67 __delay(loops_per_jiffy);
68 if (jiffies != ticks) /* longer than 1 tick */
69 loops_per_jiffy &= ~loopbit;
70 }
71
72 /* Round the value and print it */
73 printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
74 loops_per_jiffy/(500000/HZ),
75 (loops_per_jiffy/(5000/HZ)) % 100,
76 loops_per_jiffy);
77 }
78
79}
diff --git a/init/do_mounts.c b/init/do_mounts.c
new file mode 100644
index 00000000000..b7570c074d0
--- /dev/null
+++ b/init/do_mounts.c
@@ -0,0 +1,430 @@
1#include <linux/module.h>
2#include <linux/sched.h>
3#include <linux/ctype.h>
4#include <linux/fd.h>
5#include <linux/tty.h>
6#include <linux/suspend.h>
7#include <linux/root_dev.h>
8#include <linux/security.h>
9#include <linux/delay.h>
10
11#include <linux/nfs_fs.h>
12#include <linux/nfs_fs_sb.h>
13#include <linux/nfs_mount.h>
14
15#include "do_mounts.h"
16
17extern int get_filesystem_list(char * buf);
18
19int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
20
21int root_mountflags = MS_RDONLY | MS_VERBOSE;
22char * __initdata root_device_name;
23static char __initdata saved_root_name[64];
24
25/* this is initialized in init/main.c */
26dev_t ROOT_DEV;
27
28EXPORT_SYMBOL(ROOT_DEV);
29
30static int __init load_ramdisk(char *str)
31{
32 rd_doload = simple_strtol(str,NULL,0) & 3;
33 return 1;
34}
35__setup("load_ramdisk=", load_ramdisk);
36
37static int __init readonly(char *str)
38{
39 if (*str)
40 return 0;
41 root_mountflags |= MS_RDONLY;
42 return 1;
43}
44
45static int __init readwrite(char *str)
46{
47 if (*str)
48 return 0;
49 root_mountflags &= ~MS_RDONLY;
50 return 1;
51}
52
53__setup("ro", readonly);
54__setup("rw", readwrite);
55
56static dev_t try_name(char *name, int part)
57{
58 char path[64];
59 char buf[32];
60 int range;
61 dev_t res;
62 char *s;
63 int len;
64 int fd;
65 unsigned int maj, min;
66
67 /* read device number from .../dev */
68
69 sprintf(path, "/sys/block/%s/dev", name);
70 fd = sys_open(path, 0, 0);
71 if (fd < 0)
72 goto fail;
73 len = sys_read(fd, buf, 32);
74 sys_close(fd);
75 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
76 goto fail;
77 buf[len - 1] = '\0';
78 if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
79 /*
80 * Try the %u:%u format -- see print_dev_t()
81 */
82 res = MKDEV(maj, min);
83 if (maj != MAJOR(res) || min != MINOR(res))
84 goto fail;
85 } else {
86 /*
87 * Nope. Try old-style "0321"
88 */
89 res = new_decode_dev(simple_strtoul(buf, &s, 16));
90 if (*s)
91 goto fail;
92 }
93
94 /* if it's there and we are not looking for a partition - that's it */
95 if (!part)
96 return res;
97
98 /* otherwise read range from .../range */
99 sprintf(path, "/sys/block/%s/range", name);
100 fd = sys_open(path, 0, 0);
101 if (fd < 0)
102 goto fail;
103 len = sys_read(fd, buf, 32);
104 sys_close(fd);
105 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
106 goto fail;
107 buf[len - 1] = '\0';
108 range = simple_strtoul(buf, &s, 10);
109 if (*s)
110 goto fail;
111
112 /* if partition is within range - we got it */
113 if (part < range)
114 return res + part;
115fail:
116 return 0;
117}
118
119/*
120 * Convert a name into device number. We accept the following variants:
121 *
122 * 1) device number in hexadecimal represents itself
123 * 2) /dev/nfs represents Root_NFS (0xff)
124 * 3) /dev/<disk_name> represents the device number of disk
125 * 4) /dev/<disk_name><decimal> represents the device number
126 * of partition - device number of disk plus the partition number
127 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
128 * used when disk name of partitioned disk ends on a digit.
129 *
130 * If name doesn't have fall into the categories above, we return 0.
131 * Driverfs is used to check if something is a disk name - it has
132 * all known disks under bus/block/devices. If the disk name
133 * contains slashes, name of driverfs node has them replaced with
134 * bangs. try_name() does the actual checks, assuming that driverfs
135 * is mounted on rootfs /sys.
136 */
137
138dev_t name_to_dev_t(char *name)
139{
140 char s[32];
141 char *p;
142 dev_t res = 0;
143 int part;
144
145#ifdef CONFIG_SYSFS
146 int mkdir_err = sys_mkdir("/sys", 0700);
147 if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
148 goto out;
149#endif
150
151 if (strncmp(name, "/dev/", 5) != 0) {
152 unsigned maj, min;
153
154 if (sscanf(name, "%u:%u", &maj, &min) == 2) {
155 res = MKDEV(maj, min);
156 if (maj != MAJOR(res) || min != MINOR(res))
157 goto fail;
158 } else {
159 res = new_decode_dev(simple_strtoul(name, &p, 16));
160 if (*p)
161 goto fail;
162 }
163 goto done;
164 }
165 name += 5;
166 res = Root_NFS;
167 if (strcmp(name, "nfs") == 0)
168 goto done;
169 res = Root_RAM0;
170 if (strcmp(name, "ram") == 0)
171 goto done;
172
173 if (strlen(name) > 31)
174 goto fail;
175 strcpy(s, name);
176 for (p = s; *p; p++)
177 if (*p == '/')
178 *p = '!';
179 res = try_name(s, 0);
180 if (res)
181 goto done;
182
183 while (p > s && isdigit(p[-1]))
184 p--;
185 if (p == s || !*p || *p == '0')
186 goto fail;
187 part = simple_strtoul(p, NULL, 10);
188 *p = '\0';
189 res = try_name(s, part);
190 if (res)
191 goto done;
192
193 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
194 goto fail;
195 p[-1] = '\0';
196 res = try_name(s, part);
197done:
198#ifdef CONFIG_SYSFS
199 sys_umount("/sys", 0);
200out:
201 if (!mkdir_err)
202 sys_rmdir("/sys");
203#endif
204 return res;
205fail:
206 res = 0;
207 goto done;
208}
209
210static int __init root_dev_setup(char *line)
211{
212 strlcpy(saved_root_name, line, sizeof(saved_root_name));
213 return 1;
214}
215
216__setup("root=", root_dev_setup);
217
218static char * __initdata root_mount_data;
219static int __init root_data_setup(char *str)
220{
221 root_mount_data = str;
222 return 1;
223}
224
225static char * __initdata root_fs_names;
226static int __init fs_names_setup(char *str)
227{
228 root_fs_names = str;
229 return 1;
230}
231
232static unsigned int __initdata root_delay;
233static int __init root_delay_setup(char *str)
234{
235 root_delay = simple_strtoul(str, NULL, 0);
236 return 1;
237}
238
239__setup("rootflags=", root_data_setup);
240__setup("rootfstype=", fs_names_setup);
241__setup("rootdelay=", root_delay_setup);
242
243static void __init get_fs_names(char *page)
244{
245 char *s = page;
246
247 if (root_fs_names) {
248 strcpy(page, root_fs_names);
249 while (*s++) {
250 if (s[-1] == ',')
251 s[-1] = '\0';
252 }
253 } else {
254 int len = get_filesystem_list(page);
255 char *p, *next;
256
257 page[len] = '\0';
258 for (p = page-1; p; p = next) {
259 next = strchr(++p, '\n');
260 if (*p++ != '\t')
261 continue;
262 while ((*s++ = *p++) != '\n')
263 ;
264 s[-1] = '\0';
265 }
266 }
267 *s = '\0';
268}
269
270static int __init do_mount_root(char *name, char *fs, int flags, void *data)
271{
272 int err = sys_mount(name, "/root", fs, flags, data);
273 if (err)
274 return err;
275
276 sys_chdir("/root");
277 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
278 printk("VFS: Mounted root (%s filesystem)%s.\n",
279 current->fs->pwdmnt->mnt_sb->s_type->name,
280 current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ?
281 " readonly" : "");
282 return 0;
283}
284
285void __init mount_block_root(char *name, int flags)
286{
287 char *fs_names = __getname();
288 char *p;
289 char b[BDEVNAME_SIZE];
290
291 get_fs_names(fs_names);
292retry:
293 for (p = fs_names; *p; p += strlen(p)+1) {
294 int err = do_mount_root(name, p, flags, root_mount_data);
295 switch (err) {
296 case 0:
297 goto out;
298 case -EACCES:
299 flags |= MS_RDONLY;
300 goto retry;
301 case -EINVAL:
302 continue;
303 }
304 /*
305 * Allow the user to distinguish between failed sys_open
306 * and bad superblock on root device.
307 */
308 __bdevname(ROOT_DEV, b);
309 printk("VFS: Cannot open root device \"%s\" or %s\n",
310 root_device_name, b);
311 printk("Please append a correct \"root=\" boot option\n");
312
313 panic("VFS: Unable to mount root fs on %s", b);
314 }
315 panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
316out:
317 putname(fs_names);
318}
319
320#ifdef CONFIG_ROOT_NFS
321static int __init mount_nfs_root(void)
322{
323 void *data = nfs_root_data();
324
325 create_dev("/dev/root", ROOT_DEV, NULL);
326 if (data &&
327 do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
328 return 1;
329 return 0;
330}
331#endif
332
333#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
334void __init change_floppy(char *fmt, ...)
335{
336 struct termios termios;
337 char buf[80];
338 char c;
339 int fd;
340 va_list args;
341 va_start(args, fmt);
342 vsprintf(buf, fmt, args);
343 va_end(args);
344 fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
345 if (fd >= 0) {
346 sys_ioctl(fd, FDEJECT, 0);
347 sys_close(fd);
348 }
349 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
350 fd = sys_open("/dev/console", O_RDWR, 0);
351 if (fd >= 0) {
352 sys_ioctl(fd, TCGETS, (long)&termios);
353 termios.c_lflag &= ~ICANON;
354 sys_ioctl(fd, TCSETSF, (long)&termios);
355 sys_read(fd, &c, 1);
356 termios.c_lflag |= ICANON;
357 sys_ioctl(fd, TCSETSF, (long)&termios);
358 sys_close(fd);
359 }
360}
361#endif
362
363void __init mount_root(void)
364{
365#ifdef CONFIG_ROOT_NFS
366 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
367 if (mount_nfs_root())
368 return;
369
370 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
371 ROOT_DEV = Root_FD0;
372 }
373#endif
374#ifdef CONFIG_BLK_DEV_FD
375 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
376 /* rd_doload is 2 for a dual initrd/ramload setup */
377 if (rd_doload==2) {
378 if (rd_load_disk(1)) {
379 ROOT_DEV = Root_RAM1;
380 root_device_name = NULL;
381 }
382 } else
383 change_floppy("root floppy");
384 }
385#endif
386 create_dev("/dev/root", ROOT_DEV, root_device_name);
387 mount_block_root("/dev/root", root_mountflags);
388}
389
390/*
391 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
392 */
393void __init prepare_namespace(void)
394{
395 int is_floppy;
396
397 mount_devfs();
398
399 if (root_delay) {
400 printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
401 root_delay);
402 ssleep(root_delay);
403 }
404
405 md_run_setup();
406
407 if (saved_root_name[0]) {
408 root_device_name = saved_root_name;
409 ROOT_DEV = name_to_dev_t(root_device_name);
410 if (strncmp(root_device_name, "/dev/", 5) == 0)
411 root_device_name += 5;
412 }
413
414 is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
415
416 if (initrd_load())
417 goto out;
418
419 if (is_floppy && rd_doload && rd_load_disk(0))
420 ROOT_DEV = Root_RAM0;
421
422 mount_root();
423out:
424 umount_devfs("/dev");
425 sys_mount(".", "/", NULL, MS_MOVE, NULL);
426 sys_chroot(".");
427 security_sb_post_mountroot();
428 mount_devfs_fs ();
429}
430
diff --git a/init/do_mounts.h b/init/do_mounts.h
new file mode 100644
index 00000000000..de92bee4f35
--- /dev/null
+++ b/init/do_mounts.h
@@ -0,0 +1,92 @@
1#include <linux/config.h>
2#include <linux/kernel.h>
3#include <linux/devfs_fs_kernel.h>
4#include <linux/init.h>
5#include <linux/syscalls.h>
6#include <linux/unistd.h>
7#include <linux/slab.h>
8#include <linux/mount.h>
9#include <linux/major.h>
10#include <linux/root_dev.h>
11
12dev_t name_to_dev_t(char *name);
13void change_floppy(char *fmt, ...);
14void mount_block_root(char *name, int flags);
15void mount_root(void);
16extern int root_mountflags;
17extern char *root_device_name;
18
19#ifdef CONFIG_DEVFS_FS
20
21void mount_devfs(void);
22void umount_devfs(char *path);
23int create_dev(char *name, dev_t dev, char *devfs_name);
24
25#else
26
27static inline void mount_devfs(void) {}
28static inline void umount_devfs(const char *path) {}
29
30static inline int create_dev(char *name, dev_t dev, char *devfs_name)
31{
32 sys_unlink(name);
33 return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
34}
35
36#endif
37
38#if BITS_PER_LONG == 32
39static inline u32 bstat(char *name)
40{
41 struct stat64 stat;
42 if (sys_stat64(name, &stat) != 0)
43 return 0;
44 if (!S_ISBLK(stat.st_mode))
45 return 0;
46 if (stat.st_rdev != (u32)stat.st_rdev)
47 return 0;
48 return stat.st_rdev;
49}
50#else
51static inline u32 bstat(char *name)
52{
53 struct stat stat;
54 if (sys_newstat(name, &stat) != 0)
55 return 0;
56 if (!S_ISBLK(stat.st_mode))
57 return 0;
58 return stat.st_rdev;
59}
60#endif
61
62#ifdef CONFIG_BLK_DEV_RAM
63
64int __init rd_load_disk(int n);
65int __init rd_load_image(char *from);
66
67#else
68
69static inline int rd_load_disk(int n) { return 0; }
70static inline int rd_load_image(char *from) { return 0; }
71
72#endif
73
74#ifdef CONFIG_BLK_DEV_INITRD
75
76int __init initrd_load(void);
77
78#else
79
80static inline int initrd_load(void) { return 0; }
81
82#endif
83
84#ifdef CONFIG_BLK_DEV_MD
85
86void md_run_setup(void);
87
88#else
89
90static inline void md_run_setup(void) {}
91
92#endif
diff --git a/init/do_mounts_devfs.c b/init/do_mounts_devfs.c
new file mode 100644
index 00000000000..cc526474690
--- /dev/null
+++ b/init/do_mounts_devfs.c
@@ -0,0 +1,137 @@
1
2#include <linux/kernel.h>
3#include <linux/dirent.h>
4#include <linux/string.h>
5
6#include "do_mounts.h"
7
8void __init mount_devfs(void)
9{
10 sys_mount("devfs", "/dev", "devfs", 0, NULL);
11}
12
13void __init umount_devfs(char *path)
14{
15 sys_umount(path, 0);
16}
17
18/*
19 * If the dir will fit in *buf, return its length. If it won't fit, return
20 * zero. Return -ve on error.
21 */
22static int __init do_read_dir(int fd, void *buf, int len)
23{
24 long bytes, n;
25 char *p = buf;
26 sys_lseek(fd, 0, 0);
27
28 for (bytes = 0; bytes < len; bytes += n) {
29 n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes),
30 len - bytes);
31 if (n < 0)
32 return n;
33 if (n == 0)
34 return bytes;
35 }
36 return 0;
37}
38
39/*
40 * Try to read all of a directory. Returns the contents at *p, which
41 * is kmalloced memory. Returns the number of bytes read at *len. Returns
42 * NULL on error.
43 */
44static void * __init read_dir(char *path, int *len)
45{
46 int size;
47 int fd = sys_open(path, 0, 0);
48
49 *len = 0;
50 if (fd < 0)
51 return NULL;
52
53 for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) {
54 void *p = kmalloc(size, GFP_KERNEL);
55 int n;
56 if (!p)
57 break;
58 n = do_read_dir(fd, p, size);
59 if (n > 0) {
60 sys_close(fd);
61 *len = n;
62 return p;
63 }
64 kfree(p);
65 if (n == -EINVAL)
66 continue; /* Try a larger buffer */
67 if (n < 0)
68 break;
69 }
70 sys_close(fd);
71 return NULL;
72}
73
74/*
75 * recursively scan <path>, looking for a device node of type <dev>
76 */
77static int __init find_in_devfs(char *path, unsigned dev)
78{
79 char *end = path + strlen(path);
80 int rest = path + 64 - end;
81 int size;
82 char *p = read_dir(path, &size);
83 char *s;
84
85 if (!p)
86 return -1;
87 for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
88 struct linux_dirent64 *d = (struct linux_dirent64 *)s;
89 if (strlen(d->d_name) + 2 > rest)
90 continue;
91 switch (d->d_type) {
92 case DT_BLK:
93 sprintf(end, "/%s", d->d_name);
94 if (bstat(path) != dev)
95 break;
96 kfree(p);
97 return 0;
98 case DT_DIR:
99 if (strcmp(d->d_name, ".") == 0)
100 break;
101 if (strcmp(d->d_name, "..") == 0)
102 break;
103 sprintf(end, "/%s", d->d_name);
104 if (find_in_devfs(path, dev) < 0)
105 break;
106 kfree(p);
107 return 0;
108 }
109 }
110 kfree(p);
111 return -1;
112}
113
114/*
115 * create a device node called <name> which points to
116 * <devfs_name> if possible, otherwise find a device node
117 * which matches <dev> and make <name> a symlink pointing to it.
118 */
119int __init create_dev(char *name, dev_t dev, char *devfs_name)
120{
121 char path[64];
122
123 sys_unlink(name);
124 if (devfs_name && devfs_name[0]) {
125 if (strncmp(devfs_name, "/dev/", 5) == 0)
126 devfs_name += 5;
127 sprintf(path, "/dev/%s", devfs_name);
128 if (sys_access(path, 0) == 0)
129 return sys_symlink(devfs_name, name);
130 }
131 if (!dev)
132 return -1;
133 strcpy(path, "/dev");
134 if (find_in_devfs(path, new_encode_dev(dev)) < 0)
135 return -1;
136 return sys_symlink(path + 5, name);
137}
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
new file mode 100644
index 00000000000..07e7d31f2d0
--- /dev/null
+++ b/init/do_mounts_initrd.c
@@ -0,0 +1,121 @@
1#define __KERNEL_SYSCALLS__
2#include <linux/unistd.h>
3#include <linux/kernel.h>
4#include <linux/fs.h>
5#include <linux/minix_fs.h>
6#include <linux/ext2_fs.h>
7#include <linux/romfs_fs.h>
8#include <linux/initrd.h>
9#include <linux/sched.h>
10
11#include "do_mounts.h"
12
13unsigned long initrd_start, initrd_end;
14int initrd_below_start_ok;
15unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
16static int __initdata old_fd, root_fd;
17static int __initdata mount_initrd = 1;
18
19static int __init no_initrd(char *str)
20{
21 mount_initrd = 0;
22 return 1;
23}
24
25__setup("noinitrd", no_initrd);
26
27static int __init do_linuxrc(void * shell)
28{
29 static char *argv[] = { "linuxrc", NULL, };
30 extern char * envp_init[];
31
32 sys_close(old_fd);sys_close(root_fd);
33 sys_close(0);sys_close(1);sys_close(2);
34 sys_setsid();
35 (void) sys_open("/dev/console",O_RDWR,0);
36 (void) sys_dup(0);
37 (void) sys_dup(0);
38 return execve(shell, argv, envp_init);
39}
40
41static void __init handle_initrd(void)
42{
43 int error;
44 int i, pid;
45
46 real_root_dev = new_encode_dev(ROOT_DEV);
47 create_dev("/dev/root.old", Root_RAM0, NULL);
48 /* mount initrd on rootfs' /root */
49 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
50 sys_mkdir("/old", 0700);
51 root_fd = sys_open("/", 0, 0);
52 old_fd = sys_open("/old", 0, 0);
53 /* move initrd over / and chdir/chroot in initrd root */
54 sys_chdir("/root");
55 sys_mount(".", "/", NULL, MS_MOVE, NULL);
56 sys_chroot(".");
57 mount_devfs_fs ();
58
59 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
60 if (pid > 0) {
61 while (pid != sys_wait4(-1, &i, 0, NULL))
62 yield();
63 }
64
65 /* move initrd to rootfs' /old */
66 sys_fchdir(old_fd);
67 sys_mount("/", ".", NULL, MS_MOVE, NULL);
68 /* switch root and cwd back to / of rootfs */
69 sys_fchdir(root_fd);
70 sys_chroot(".");
71 sys_close(old_fd);
72 sys_close(root_fd);
73 umount_devfs("/old/dev");
74
75 if (new_decode_dev(real_root_dev) == Root_RAM0) {
76 sys_chdir("/old");
77 return;
78 }
79
80 ROOT_DEV = new_decode_dev(real_root_dev);
81 mount_root();
82
83 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
84 error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
85 if (!error)
86 printk("okay\n");
87 else {
88 int fd = sys_open("/dev/root.old", O_RDWR, 0);
89 printk("failed\n");
90 printk(KERN_NOTICE "Unmounting old root\n");
91 sys_umount("/old", MNT_DETACH);
92 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
93 if (fd < 0) {
94 error = fd;
95 } else {
96 error = sys_ioctl(fd, BLKFLSBUF, 0);
97 sys_close(fd);
98 }
99 printk(!error ? "okay\n" : "failed\n");
100 }
101}
102
103int __init initrd_load(void)
104{
105 if (mount_initrd) {
106 create_dev("/dev/ram", Root_RAM0, NULL);
107 /*
108 * Load the initrd data into /dev/ram0. Execute it as initrd
109 * unless /dev/ram0 is supposed to be our actual root device,
110 * in that case the ram disk is just set up here, and gets
111 * mounted in the normal path.
112 */
113 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
114 sys_unlink("/initrd.image");
115 handle_initrd();
116 return 1;
117 }
118 }
119 sys_unlink("/initrd.image");
120 return 0;
121}
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
new file mode 100644
index 00000000000..3fbc3555ce9
--- /dev/null
+++ b/init/do_mounts_md.c
@@ -0,0 +1,290 @@
1
2#include <linux/raid/md.h>
3
4#include "do_mounts.h"
5
6/*
7 * When md (and any require personalities) are compiled into the kernel
8 * (not a module), arrays can be assembles are boot time using with AUTODETECT
9 * where specially marked partitions are registered with md_autodetect_dev(),
10 * and with MD_BOOT where devices to be collected are given on the boot line
11 * with md=.....
12 * The code for that is here.
13 */
14
15static int __initdata raid_noautodetect, raid_autopart;
16
17static struct {
18 int minor;
19 int partitioned;
20 int pers;
21 int chunk;
22 char *device_names;
23} md_setup_args[MAX_MD_DEVS] __initdata;
24
25static int md_setup_ents __initdata;
26
27extern int mdp_major;
28/*
29 * Parse the command-line parameters given our kernel, but do not
30 * actually try to invoke the MD device now; that is handled by
31 * md_setup_drive after the low-level disk drivers have initialised.
32 *
33 * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
34 * assigns the task of parsing integer arguments to the
35 * invoked program now). Added ability to initialise all
36 * the MD devices (by specifying multiple "md=" lines)
37 * instead of just one. -- KTK
38 * 18May2000: Added support for persistent-superblock arrays:
39 * md=n,0,factor,fault,device-list uses RAID0 for device n
40 * md=n,-1,factor,fault,device-list uses LINEAR for device n
41 * md=n,device-list reads a RAID superblock from the devices
42 * elements in device-list are read by name_to_kdev_t so can be
43 * a hex number or something like /dev/hda1 /dev/sdb
44 * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
45 * Shifted name_to_kdev_t() and related operations to md_set_drive()
46 * for later execution. Rewrote section to make devfs compatible.
47 */
48static int __init md_setup(char *str)
49{
50 int minor, level, factor, fault, pers, partitioned = 0;
51 char *pername = "";
52 char *str1;
53 int ent;
54
55 if (*str == 'd') {
56 partitioned = 1;
57 str++;
58 }
59 if (get_option(&str, &minor) != 2) { /* MD Number */
60 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
61 return 0;
62 }
63 str1 = str;
64 if (minor >= MAX_MD_DEVS) {
65 printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
66 return 0;
67 }
68 for (ent=0 ; ent< md_setup_ents ; ent++)
69 if (md_setup_args[ent].minor == minor &&
70 md_setup_args[ent].partitioned == partitioned) {
71 printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
72 "Replacing previous definition.\n", partitioned?"d":"", minor);
73 break;
74 }
75 if (ent >= MAX_MD_DEVS) {
76 printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
77 return 0;
78 }
79 if (ent >= md_setup_ents)
80 md_setup_ents++;
81 switch (get_option(&str, &level)) { /* RAID Personality */
82 case 2: /* could be 0 or -1.. */
83 if (level == 0 || level == LEVEL_LINEAR) {
84 if (get_option(&str, &factor) != 2 || /* Chunk Size */
85 get_option(&str, &fault) != 2) {
86 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
87 return 0;
88 }
89 md_setup_args[ent].pers = level;
90 md_setup_args[ent].chunk = 1 << (factor+12);
91 if (level == LEVEL_LINEAR) {
92 pers = LINEAR;
93 pername = "linear";
94 } else {
95 pers = RAID0;
96 pername = "raid0";
97 }
98 md_setup_args[ent].pers = pers;
99 break;
100 }
101 /* FALL THROUGH */
102 case 1: /* the first device is numeric */
103 str = str1;
104 /* FALL THROUGH */
105 case 0:
106 md_setup_args[ent].pers = 0;
107 pername="super-block";
108 }
109
110 printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
111 minor, pername, str);
112 md_setup_args[ent].device_names = str;
113 md_setup_args[ent].partitioned = partitioned;
114 md_setup_args[ent].minor = minor;
115
116 return 1;
117}
118
119#define MdpMinorShift 6
120
121static void __init md_setup_drive(void)
122{
123 int minor, i, ent, partitioned;
124 dev_t dev;
125 dev_t devices[MD_SB_DISKS+1];
126
127 for (ent = 0; ent < md_setup_ents ; ent++) {
128 int fd;
129 int err = 0;
130 char *devname;
131 mdu_disk_info_t dinfo;
132 char name[16], devfs_name[16];
133
134 minor = md_setup_args[ent].minor;
135 partitioned = md_setup_args[ent].partitioned;
136 devname = md_setup_args[ent].device_names;
137
138 sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
139 sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
140 if (partitioned)
141 dev = MKDEV(mdp_major, minor << MdpMinorShift);
142 else
143 dev = MKDEV(MD_MAJOR, minor);
144 create_dev(name, dev, devfs_name);
145 for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
146 char *p;
147 char comp_name[64];
148 u32 rdev;
149
150 p = strchr(devname, ',');
151 if (p)
152 *p++ = 0;
153
154 dev = name_to_dev_t(devname);
155 if (strncmp(devname, "/dev/", 5) == 0)
156 devname += 5;
157 snprintf(comp_name, 63, "/dev/%s", devname);
158 rdev = bstat(comp_name);
159 if (rdev)
160 dev = new_decode_dev(rdev);
161 if (!dev) {
162 printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
163 break;
164 }
165
166 devices[i] = dev;
167
168 devname = p;
169 }
170 devices[i] = 0;
171
172 if (!i)
173 continue;
174
175 printk(KERN_INFO "md: Loading md%s%d: %s\n",
176 partitioned ? "_d" : "", minor,
177 md_setup_args[ent].device_names);
178
179 fd = sys_open(name, 0, 0);
180 if (fd < 0) {
181 printk(KERN_ERR "md: open failed - cannot start "
182 "array %s\n", name);
183 continue;
184 }
185 if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
186 printk(KERN_WARNING
187 "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
188 minor);
189 sys_close(fd);
190 continue;
191 }
192
193 if (md_setup_args[ent].pers) {
194 /* non-persistent */
195 mdu_array_info_t ainfo;
196 ainfo.level = pers_to_level(md_setup_args[ent].pers);
197 ainfo.size = 0;
198 ainfo.nr_disks =0;
199 ainfo.raid_disks =0;
200 while (devices[ainfo.raid_disks])
201 ainfo.raid_disks++;
202 ainfo.md_minor =minor;
203 ainfo.not_persistent = 1;
204
205 ainfo.state = (1 << MD_SB_CLEAN);
206 ainfo.layout = 0;
207 ainfo.chunk_size = md_setup_args[ent].chunk;
208 err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
209 for (i = 0; !err && i <= MD_SB_DISKS; i++) {
210 dev = devices[i];
211 if (!dev)
212 break;
213 dinfo.number = i;
214 dinfo.raid_disk = i;
215 dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
216 dinfo.major = MAJOR(dev);
217 dinfo.minor = MINOR(dev);
218 err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
219 }
220 } else {
221 /* persistent */
222 for (i = 0; i <= MD_SB_DISKS; i++) {
223 dev = devices[i];
224 if (!dev)
225 break;
226 dinfo.major = MAJOR(dev);
227 dinfo.minor = MINOR(dev);
228 sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
229 }
230 }
231 if (!err)
232 err = sys_ioctl(fd, RUN_ARRAY, 0);
233 if (err)
234 printk(KERN_WARNING "md: starting md%d failed\n", minor);
235 else {
236 /* reread the partition table.
237 * I (neilb) and not sure why this is needed, but I cannot
238 * boot a kernel with devfs compiled in from partitioned md
239 * array without it
240 */
241 sys_close(fd);
242 fd = sys_open(name, 0, 0);
243 sys_ioctl(fd, BLKRRPART, 0);
244 }
245 sys_close(fd);
246 }
247}
248
249static int __init raid_setup(char *str)
250{
251 int len, pos;
252
253 len = strlen(str) + 1;
254 pos = 0;
255
256 while (pos < len) {
257 char *comma = strchr(str+pos, ',');
258 int wlen;
259 if (comma)
260 wlen = (comma-str)-pos;
261 else wlen = (len-1)-pos;
262
263 if (!strncmp(str, "noautodetect", wlen))
264 raid_noautodetect = 1;
265 if (strncmp(str, "partitionable", wlen)==0)
266 raid_autopart = 1;
267 if (strncmp(str, "part", wlen)==0)
268 raid_autopart = 1;
269 pos += wlen+1;
270 }
271 return 1;
272}
273
274__setup("raid=", raid_setup);
275__setup("md=", md_setup);
276
277void __init md_run_setup(void)
278{
279 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
280 if (raid_noautodetect)
281 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
282 else {
283 int fd = sys_open("/dev/md0", 0, 0);
284 if (fd >= 0) {
285 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
286 sys_close(fd);
287 }
288 }
289 md_setup_drive();
290}
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
new file mode 100644
index 00000000000..c10b08a8098
--- /dev/null
+++ b/init/do_mounts_rd.c
@@ -0,0 +1,429 @@
1
2#include <linux/kernel.h>
3#include <linux/fs.h>
4#include <linux/minix_fs.h>
5#include <linux/ext2_fs.h>
6#include <linux/romfs_fs.h>
7#include <linux/cramfs_fs.h>
8#include <linux/initrd.h>
9#include <linux/string.h>
10
11#include "do_mounts.h"
12
13#define BUILD_CRAMDISK
14
15int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
16
17static int __init prompt_ramdisk(char *str)
18{
19 rd_prompt = simple_strtol(str,NULL,0) & 1;
20 return 1;
21}
22__setup("prompt_ramdisk=", prompt_ramdisk);
23
24int __initdata rd_image_start; /* starting block # of image */
25
26static int __init ramdisk_start_setup(char *str)
27{
28 rd_image_start = simple_strtol(str,NULL,0);
29 return 1;
30}
31__setup("ramdisk_start=", ramdisk_start_setup);
32
33static int __init crd_load(int in_fd, int out_fd);
34
35/*
36 * This routine tries to find a RAM disk image to load, and returns the
37 * number of blocks to read for a non-compressed image, 0 if the image
38 * is a compressed image, and -1 if an image with the right magic
39 * numbers could not be found.
40 *
41 * We currently check for the following magic numbers:
42 * minix
43 * ext2
44 * romfs
45 * cramfs
46 * gzip
47 */
48static int __init
49identify_ramdisk_image(int fd, int start_block)
50{
51 const int size = 512;
52 struct minix_super_block *minixsb;
53 struct ext2_super_block *ext2sb;
54 struct romfs_super_block *romfsb;
55 struct cramfs_super *cramfsb;
56 int nblocks = -1;
57 unsigned char *buf;
58
59 buf = kmalloc(size, GFP_KERNEL);
60 if (buf == 0)
61 return -1;
62
63 minixsb = (struct minix_super_block *) buf;
64 ext2sb = (struct ext2_super_block *) buf;
65 romfsb = (struct romfs_super_block *) buf;
66 cramfsb = (struct cramfs_super *) buf;
67 memset(buf, 0xe5, size);
68
69 /*
70 * Read block 0 to test for gzipped kernel
71 */
72 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
73 sys_read(fd, buf, size);
74
75 /*
76 * If it matches the gzip magic numbers, return -1
77 */
78 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
79 printk(KERN_NOTICE
80 "RAMDISK: Compressed image found at block %d\n",
81 start_block);
82 nblocks = 0;
83 goto done;
84 }
85
86 /* romfs is at block zero too */
87 if (romfsb->word0 == ROMSB_WORD0 &&
88 romfsb->word1 == ROMSB_WORD1) {
89 printk(KERN_NOTICE
90 "RAMDISK: romfs filesystem found at block %d\n",
91 start_block);
92 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
93 goto done;
94 }
95
96 if (cramfsb->magic == CRAMFS_MAGIC) {
97 printk(KERN_NOTICE
98 "RAMDISK: cramfs filesystem found at block %d\n",
99 start_block);
100 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
101 goto done;
102 }
103
104 /*
105 * Read block 1 to test for minix and ext2 superblock
106 */
107 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
108 sys_read(fd, buf, size);
109
110 /* Try minix */
111 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
112 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
113 printk(KERN_NOTICE
114 "RAMDISK: Minix filesystem found at block %d\n",
115 start_block);
116 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
117 goto done;
118 }
119
120 /* Try ext2 */
121 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
122 printk(KERN_NOTICE
123 "RAMDISK: ext2 filesystem found at block %d\n",
124 start_block);
125 nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
126 le32_to_cpu(ext2sb->s_log_block_size);
127 goto done;
128 }
129
130 printk(KERN_NOTICE
131 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
132 start_block);
133
134done:
135 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
136 kfree(buf);
137 return nblocks;
138}
139
140int __init rd_load_image(char *from)
141{
142 int res = 0;
143 int in_fd, out_fd;
144 unsigned long rd_blocks, devblocks;
145 int nblocks, i, disk;
146 char *buf = NULL;
147 unsigned short rotate = 0;
148#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
149 char rotator[4] = { '|' , '/' , '-' , '\\' };
150#endif
151
152 out_fd = sys_open("/dev/ram", O_RDWR, 0);
153 if (out_fd < 0)
154 goto out;
155
156 in_fd = sys_open(from, O_RDONLY, 0);
157 if (in_fd < 0)
158 goto noclose_input;
159
160 nblocks = identify_ramdisk_image(in_fd, rd_image_start);
161 if (nblocks < 0)
162 goto done;
163
164 if (nblocks == 0) {
165#ifdef BUILD_CRAMDISK
166 if (crd_load(in_fd, out_fd) == 0)
167 goto successful_load;
168#else
169 printk(KERN_NOTICE
170 "RAMDISK: Kernel does not support compressed "
171 "RAM disk images\n");
172#endif
173 goto done;
174 }
175
176 /*
177 * NOTE NOTE: nblocks is not actually blocks but
178 * the number of kibibytes of data to load into a ramdisk.
179 * So any ramdisk block size that is a multiple of 1KiB should
180 * work when the appropriate ramdisk_blocksize is specified
181 * on the command line.
182 *
183 * The default ramdisk_blocksize is 1KiB and it is generally
184 * silly to use anything else, so make sure to use 1KiB
185 * blocksize while generating ext2fs ramdisk-images.
186 */
187 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
188 rd_blocks = 0;
189 else
190 rd_blocks >>= 1;
191
192 if (nblocks > rd_blocks) {
193 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
194 nblocks, rd_blocks);
195 goto done;
196 }
197
198 /*
199 * OK, time to copy in the data
200 */
201 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
202 devblocks = 0;
203 else
204 devblocks >>= 1;
205
206 if (strcmp(from, "/initrd.image") == 0)
207 devblocks = nblocks;
208
209 if (devblocks == 0) {
210 printk(KERN_ERR "RAMDISK: could not determine device size\n");
211 goto done;
212 }
213
214 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
215 if (buf == 0) {
216 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
217 goto done;
218 }
219
220 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
221 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
222 for (i = 0, disk = 1; i < nblocks; i++) {
223 if (i && (i % devblocks == 0)) {
224 printk("done disk #%d.\n", disk++);
225 rotate = 0;
226 if (sys_close(in_fd)) {
227 printk("Error closing the disk.\n");
228 goto noclose_input;
229 }
230 change_floppy("disk #%d", disk);
231 in_fd = sys_open(from, O_RDONLY, 0);
232 if (in_fd < 0) {
233 printk("Error opening disk.\n");
234 goto noclose_input;
235 }
236 printk("Loading disk #%d... ", disk);
237 }
238 sys_read(in_fd, buf, BLOCK_SIZE);
239 sys_write(out_fd, buf, BLOCK_SIZE);
240#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
241 if (!(i % 16)) {
242 printk("%c\b", rotator[rotate & 0x3]);
243 rotate++;
244 }
245#endif
246 }
247 printk("done.\n");
248
249successful_load:
250 res = 1;
251done:
252 sys_close(in_fd);
253noclose_input:
254 sys_close(out_fd);
255out:
256 kfree(buf);
257 sys_unlink("/dev/ram");
258 return res;
259}
260
261int __init rd_load_disk(int n)
262{
263 if (rd_prompt)
264 change_floppy("root floppy disk to be loaded into RAM disk");
265 create_dev("/dev/root", ROOT_DEV, root_device_name);
266 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
267 return rd_load_image("/dev/root");
268}
269
270#ifdef BUILD_CRAMDISK
271
272/*
273 * gzip declarations
274 */
275
276#define OF(args) args
277
278#ifndef memzero
279#define memzero(s, n) memset ((s), 0, (n))
280#endif
281
282typedef unsigned char uch;
283typedef unsigned short ush;
284typedef unsigned long ulg;
285
286#define INBUFSIZ 4096
287#define WSIZE 0x8000 /* window size--must be a power of two, and */
288 /* at least 32K for zip's deflate method */
289
290static uch *inbuf;
291static uch *window;
292
293static unsigned insize; /* valid bytes in inbuf */
294static unsigned inptr; /* index of next byte to be processed in inbuf */
295static unsigned outcnt; /* bytes in output buffer */
296static int exit_code;
297static int unzip_error;
298static long bytes_out;
299static int crd_infd, crd_outfd;
300
301#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
302
303/* Diagnostic functions (stubbed out) */
304#define Assert(cond,msg)
305#define Trace(x)
306#define Tracev(x)
307#define Tracevv(x)
308#define Tracec(c,x)
309#define Tracecv(c,x)
310
311#define STATIC static
312#define INIT __init
313
314static int __init fill_inbuf(void);
315static void __init flush_window(void);
316static void __init *malloc(size_t size);
317static void __init free(void *where);
318static void __init error(char *m);
319static void __init gzip_mark(void **);
320static void __init gzip_release(void **);
321
322#include "../lib/inflate.c"
323
324static void __init *malloc(size_t size)
325{
326 return kmalloc(size, GFP_KERNEL);
327}
328
329static void __init free(void *where)
330{
331 kfree(where);
332}
333
334static void __init gzip_mark(void **ptr)
335{
336}
337
338static void __init gzip_release(void **ptr)
339{
340}
341
342
343/* ===========================================================================
344 * Fill the input buffer. This is called only when the buffer is empty
345 * and at least one byte is really needed.
346 * Returning -1 does not guarantee that gunzip() will ever return.
347 */
348static int __init fill_inbuf(void)
349{
350 if (exit_code) return -1;
351
352 insize = sys_read(crd_infd, inbuf, INBUFSIZ);
353 if (insize == 0) {
354 error("RAMDISK: ran out of compressed data");
355 return -1;
356 }
357
358 inptr = 1;
359
360 return inbuf[0];
361}
362
363/* ===========================================================================
364 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
365 * (Used for the decompressed data only.)
366 */
367static void __init flush_window(void)
368{
369 ulg c = crc; /* temporary variable */
370 unsigned n, written;
371 uch *in, ch;
372
373 written = sys_write(crd_outfd, window, outcnt);
374 if (written != outcnt && unzip_error == 0) {
375 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
376 written, outcnt, bytes_out);
377 unzip_error = 1;
378 }
379 in = window;
380 for (n = 0; n < outcnt; n++) {
381 ch = *in++;
382 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
383 }
384 crc = c;
385 bytes_out += (ulg)outcnt;
386 outcnt = 0;
387}
388
389static void __init error(char *x)
390{
391 printk(KERN_ERR "%s\n", x);
392 exit_code = 1;
393 unzip_error = 1;
394}
395
396static int __init crd_load(int in_fd, int out_fd)
397{
398 int result;
399
400 insize = 0; /* valid bytes in inbuf */
401 inptr = 0; /* index of next byte to be processed in inbuf */
402 outcnt = 0; /* bytes in output buffer */
403 exit_code = 0;
404 bytes_out = 0;
405 crc = (ulg)0xffffffffL; /* shift register contents */
406
407 crd_infd = in_fd;
408 crd_outfd = out_fd;
409 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
410 if (inbuf == 0) {
411 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
412 return -1;
413 }
414 window = kmalloc(WSIZE, GFP_KERNEL);
415 if (window == 0) {
416 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
417 kfree(inbuf);
418 return -1;
419 }
420 makecrc();
421 result = gunzip();
422 if (unzip_error)
423 result = 1;
424 kfree(inbuf);
425 kfree(window);
426 return result;
427}
428
429#endif /* BUILD_CRAMDISK */
diff --git a/init/initramfs.c b/init/initramfs.c
new file mode 100644
index 00000000000..02c5ce64990
--- /dev/null
+++ b/init/initramfs.c
@@ -0,0 +1,500 @@
1#include <linux/init.h>
2#include <linux/fs.h>
3#include <linux/slab.h>
4#include <linux/types.h>
5#include <linux/fcntl.h>
6#include <linux/delay.h>
7#include <linux/string.h>
8#include <linux/syscalls.h>
9
10static __initdata char *message;
11static void __init error(char *x)
12{
13 if (!message)
14 message = x;
15}
16
17static void __init *malloc(size_t size)
18{
19 return kmalloc(size, GFP_KERNEL);
20}
21
22static void __init free(void *where)
23{
24 kfree(where);
25}
26
27/* link hash */
28
29static __initdata struct hash {
30 int ino, minor, major;
31 struct hash *next;
32 char *name;
33} *head[32];
34
35static inline int hash(int major, int minor, int ino)
36{
37 unsigned long tmp = ino + minor + (major << 3);
38 tmp += tmp >> 5;
39 return tmp & 31;
40}
41
42static char __init *find_link(int major, int minor, int ino, char *name)
43{
44 struct hash **p, *q;
45 for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) {
46 if ((*p)->ino != ino)
47 continue;
48 if ((*p)->minor != minor)
49 continue;
50 if ((*p)->major != major)
51 continue;
52 return (*p)->name;
53 }
54 q = (struct hash *)malloc(sizeof(struct hash));
55 if (!q)
56 panic("can't allocate link hash entry");
57 q->ino = ino;
58 q->minor = minor;
59 q->major = major;
60 q->name = name;
61 q->next = NULL;
62 *p = q;
63 return NULL;
64}
65
66static void __init free_hash(void)
67{
68 struct hash **p, *q;
69 for (p = head; p < head + 32; p++) {
70 while (*p) {
71 q = *p;
72 *p = q->next;
73 free(q);
74 }
75 }
76}
77
78/* cpio header parsing */
79
80static __initdata unsigned long ino, major, minor, nlink;
81static __initdata mode_t mode;
82static __initdata unsigned long body_len, name_len;
83static __initdata uid_t uid;
84static __initdata gid_t gid;
85static __initdata unsigned rdev;
86
87static void __init parse_header(char *s)
88{
89 unsigned long parsed[12];
90 char buf[9];
91 int i;
92
93 buf[8] = '\0';
94 for (i = 0, s += 6; i < 12; i++, s += 8) {
95 memcpy(buf, s, 8);
96 parsed[i] = simple_strtoul(buf, NULL, 16);
97 }
98 ino = parsed[0];
99 mode = parsed[1];
100 uid = parsed[2];
101 gid = parsed[3];
102 nlink = parsed[4];
103 body_len = parsed[6];
104 major = parsed[7];
105 minor = parsed[8];
106 rdev = new_encode_dev(MKDEV(parsed[9], parsed[10]));
107 name_len = parsed[11];
108}
109
110/* FSM */
111
112static __initdata enum state {
113 Start,
114 Collect,
115 GotHeader,
116 SkipIt,
117 GotName,
118 CopyFile,
119 GotSymlink,
120 Reset
121} state, next_state;
122
123static __initdata char *victim;
124static __initdata unsigned count;
125static __initdata loff_t this_header, next_header;
126
127static __initdata int dry_run;
128
129static inline void eat(unsigned n)
130{
131 victim += n;
132 this_header += n;
133 count -= n;
134}
135
136#define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
137
138static __initdata char *collected;
139static __initdata int remains;
140static __initdata char *collect;
141
142static void __init read_into(char *buf, unsigned size, enum state next)
143{
144 if (count >= size) {
145 collected = victim;
146 eat(size);
147 state = next;
148 } else {
149 collect = collected = buf;
150 remains = size;
151 next_state = next;
152 state = Collect;
153 }
154}
155
156static __initdata char *header_buf, *symlink_buf, *name_buf;
157
158static int __init do_start(void)
159{
160 read_into(header_buf, 110, GotHeader);
161 return 0;
162}
163
164static int __init do_collect(void)
165{
166 unsigned n = remains;
167 if (count < n)
168 n = count;
169 memcpy(collect, victim, n);
170 eat(n);
171 collect += n;
172 if ((remains -= n) != 0)
173 return 1;
174 state = next_state;
175 return 0;
176}
177
178static int __init do_header(void)
179{
180 if (memcmp(collected, "070701", 6)) {
181 error("no cpio magic");
182 return 1;
183 }
184 parse_header(collected);
185 next_header = this_header + N_ALIGN(name_len) + body_len;
186 next_header = (next_header + 3) & ~3;
187 if (dry_run) {
188 read_into(name_buf, N_ALIGN(name_len), GotName);
189 return 0;
190 }
191 state = SkipIt;
192 if (name_len <= 0 || name_len > PATH_MAX)
193 return 0;
194 if (S_ISLNK(mode)) {
195 if (body_len > PATH_MAX)
196 return 0;
197 collect = collected = symlink_buf;
198 remains = N_ALIGN(name_len) + body_len;
199 next_state = GotSymlink;
200 state = Collect;
201 return 0;
202 }
203 if (S_ISREG(mode) || !body_len)
204 read_into(name_buf, N_ALIGN(name_len), GotName);
205 return 0;
206}
207
208static int __init do_skip(void)
209{
210 if (this_header + count < next_header) {
211 eat(count);
212 return 1;
213 } else {
214 eat(next_header - this_header);
215 state = next_state;
216 return 0;
217 }
218}
219
220static int __init do_reset(void)
221{
222 while(count && *victim == '\0')
223 eat(1);
224 if (count && (this_header & 3))
225 error("broken padding");
226 return 1;
227}
228
229static int __init maybe_link(void)
230{
231 if (nlink >= 2) {
232 char *old = find_link(major, minor, ino, collected);
233 if (old)
234 return (sys_link(old, collected) < 0) ? -1 : 1;
235 }
236 return 0;
237}
238
239static __initdata int wfd;
240
241static int __init do_name(void)
242{
243 state = SkipIt;
244 next_state = Reset;
245 if (strcmp(collected, "TRAILER!!!") == 0) {
246 free_hash();
247 return 0;
248 }
249 if (dry_run)
250 return 0;
251 if (S_ISREG(mode)) {
252 if (maybe_link() >= 0) {
253 wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
254 if (wfd >= 0) {
255 sys_fchown(wfd, uid, gid);
256 sys_fchmod(wfd, mode);
257 state = CopyFile;
258 }
259 }
260 } else if (S_ISDIR(mode)) {
261 sys_mkdir(collected, mode);
262 sys_chown(collected, uid, gid);
263 sys_chmod(collected, mode);
264 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
265 S_ISFIFO(mode) || S_ISSOCK(mode)) {
266 if (maybe_link() == 0) {
267 sys_mknod(collected, mode, rdev);
268 sys_chown(collected, uid, gid);
269 sys_chmod(collected, mode);
270 }
271 }
272 return 0;
273}
274
275static int __init do_copy(void)
276{
277 if (count >= body_len) {
278 sys_write(wfd, victim, body_len);
279 sys_close(wfd);
280 eat(body_len);
281 state = SkipIt;
282 return 0;
283 } else {
284 sys_write(wfd, victim, count);
285 body_len -= count;
286 eat(count);
287 return 1;
288 }
289}
290
291static int __init do_symlink(void)
292{
293 collected[N_ALIGN(name_len) + body_len] = '\0';
294 sys_symlink(collected + N_ALIGN(name_len), collected);
295 sys_lchown(collected, uid, gid);
296 state = SkipIt;
297 next_state = Reset;
298 return 0;
299}
300
301static __initdata int (*actions[])(void) = {
302 [Start] = do_start,
303 [Collect] = do_collect,
304 [GotHeader] = do_header,
305 [SkipIt] = do_skip,
306 [GotName] = do_name,
307 [CopyFile] = do_copy,
308 [GotSymlink] = do_symlink,
309 [Reset] = do_reset,
310};
311
312static int __init write_buffer(char *buf, unsigned len)
313{
314 count = len;
315 victim = buf;
316
317 while (!actions[state]())
318 ;
319 return len - count;
320}
321
322static void __init flush_buffer(char *buf, unsigned len)
323{
324 int written;
325 if (message)
326 return;
327 while ((written = write_buffer(buf, len)) < len && !message) {
328 char c = buf[written];
329 if (c == '0') {
330 buf += written;
331 len -= written;
332 state = Start;
333 } else if (c == 0) {
334 buf += written;
335 len -= written;
336 state = Reset;
337 } else
338 error("junk in compressed archive");
339 }
340}
341
342/*
343 * gzip declarations
344 */
345
346#define OF(args) args
347
348#ifndef memzero
349#define memzero(s, n) memset ((s), 0, (n))
350#endif
351
352typedef unsigned char uch;
353typedef unsigned short ush;
354typedef unsigned long ulg;
355
356#define WSIZE 0x8000 /* window size--must be a power of two, and */
357 /* at least 32K for zip's deflate method */
358
359static uch *inbuf;
360static uch *window;
361
362static unsigned insize; /* valid bytes in inbuf */
363static unsigned inptr; /* index of next byte to be processed in inbuf */
364static unsigned outcnt; /* bytes in output buffer */
365static long bytes_out;
366
367#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
368
369/* Diagnostic functions (stubbed out) */
370#define Assert(cond,msg)
371#define Trace(x)
372#define Tracev(x)
373#define Tracevv(x)
374#define Tracec(c,x)
375#define Tracecv(c,x)
376
377#define STATIC static
378#define INIT __init
379
380static void __init flush_window(void);
381static void __init error(char *m);
382static void __init gzip_mark(void **);
383static void __init gzip_release(void **);
384
385#include "../lib/inflate.c"
386
387static void __init gzip_mark(void **ptr)
388{
389}
390
391static void __init gzip_release(void **ptr)
392{
393}
394
395/* ===========================================================================
396 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
397 * (Used for the decompressed data only.)
398 */
399static void __init flush_window(void)
400{
401 ulg c = crc; /* temporary variable */
402 unsigned n;
403 uch *in, ch;
404
405 flush_buffer(window, outcnt);
406 in = window;
407 for (n = 0; n < outcnt; n++) {
408 ch = *in++;
409 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
410 }
411 crc = c;
412 bytes_out += (ulg)outcnt;
413 outcnt = 0;
414}
415
416static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
417{
418 int written;
419 dry_run = check_only;
420 header_buf = malloc(110);
421 symlink_buf = malloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1);
422 name_buf = malloc(N_ALIGN(PATH_MAX));
423 window = malloc(WSIZE);
424 if (!window || !header_buf || !symlink_buf || !name_buf)
425 panic("can't allocate buffers");
426 state = Start;
427 this_header = 0;
428 message = NULL;
429 while (!message && len) {
430 loff_t saved_offset = this_header;
431 if (*buf == '0' && !(this_header & 3)) {
432 state = Start;
433 written = write_buffer(buf, len);
434 buf += written;
435 len -= written;
436 continue;
437 }
438 if (!*buf) {
439 buf++;
440 len--;
441 this_header++;
442 continue;
443 }
444 this_header = 0;
445 insize = len;
446 inbuf = buf;
447 inptr = 0;
448 outcnt = 0; /* bytes in output buffer */
449 bytes_out = 0;
450 crc = (ulg)0xffffffffL; /* shift register contents */
451 makecrc();
452 gunzip();
453 if (state != Reset)
454 error("junk in gzipped archive");
455 this_header = saved_offset + inptr;
456 buf += inptr;
457 len -= inptr;
458 }
459 free(window);
460 free(name_buf);
461 free(symlink_buf);
462 free(header_buf);
463 return message;
464}
465
466extern char __initramfs_start[], __initramfs_end[];
467#ifdef CONFIG_BLK_DEV_INITRD
468#include <linux/initrd.h>
469#endif
470
471void __init populate_rootfs(void)
472{
473 char *err = unpack_to_rootfs(__initramfs_start,
474 __initramfs_end - __initramfs_start, 0);
475 if (err)
476 panic(err);
477#ifdef CONFIG_BLK_DEV_INITRD
478 if (initrd_start) {
479 int fd;
480 printk(KERN_INFO "checking if image is initramfs...");
481 err = unpack_to_rootfs((char *)initrd_start,
482 initrd_end - initrd_start, 1);
483 if (!err) {
484 printk(" it is\n");
485 unpack_to_rootfs((char *)initrd_start,
486 initrd_end - initrd_start, 0);
487 free_initrd_mem(initrd_start, initrd_end);
488 return;
489 }
490 printk("it isn't (%s); looks like an initrd\n", err);
491 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 700);
492 if (fd >= 0) {
493 sys_write(fd, (char *)initrd_start,
494 initrd_end - initrd_start);
495 sys_close(fd);
496 free_initrd_mem(initrd_start, initrd_end);
497 }
498 }
499#endif
500}
diff --git a/init/main.c b/init/main.c
new file mode 100644
index 00000000000..40bf367ffdf
--- /dev/null
+++ b/init/main.c
@@ -0,0 +1,713 @@
1/*
2 * linux/init/main.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * GK 2/5/95 - Changed to support mounting root fs via NFS
7 * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
8 * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
9 * Simplified starting of init: Michael A. Griffith <grif@acm.org>
10 */
11
12#define __KERNEL_SYSCALLS__
13
14#include <linux/config.h>
15#include <linux/types.h>
16#include <linux/module.h>
17#include <linux/proc_fs.h>
18#include <linux/devfs_fs_kernel.h>
19#include <linux/kernel.h>
20#include <linux/syscalls.h>
21#include <linux/string.h>
22#include <linux/ctype.h>
23#include <linux/delay.h>
24#include <linux/utsname.h>
25#include <linux/ioport.h>
26#include <linux/init.h>
27#include <linux/smp_lock.h>
28#include <linux/initrd.h>
29#include <linux/hdreg.h>
30#include <linux/bootmem.h>
31#include <linux/tty.h>
32#include <linux/gfp.h>
33#include <linux/percpu.h>
34#include <linux/kmod.h>
35#include <linux/kernel_stat.h>
36#include <linux/security.h>
37#include <linux/workqueue.h>
38#include <linux/profile.h>
39#include <linux/rcupdate.h>
40#include <linux/moduleparam.h>
41#include <linux/kallsyms.h>
42#include <linux/writeback.h>
43#include <linux/cpu.h>
44#include <linux/cpuset.h>
45#include <linux/efi.h>
46#include <linux/unistd.h>
47#include <linux/rmap.h>
48#include <linux/mempolicy.h>
49#include <linux/key.h>
50
51#include <asm/io.h>
52#include <asm/bugs.h>
53#include <asm/setup.h>
54
55/*
56 * This is one of the first .c files built. Error out early
57 * if we have compiler trouble..
58 */
59#if __GNUC__ == 2 && __GNUC_MINOR__ == 96
60#ifdef CONFIG_FRAME_POINTER
61#error This compiler cannot compile correctly with frame pointers enabled
62#endif
63#endif
64
65#ifdef CONFIG_X86_LOCAL_APIC
66#include <asm/smp.h>
67#endif
68
69/*
70 * Versions of gcc older than that listed below may actually compile
71 * and link okay, but the end product can have subtle run time bugs.
72 * To avoid associated bogus bug reports, we flatly refuse to compile
73 * with a gcc that is known to be too old from the very beginning.
74 */
75#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
76#error Sorry, your GCC is too old. It builds incorrect kernels.
77#endif
78
79static int init(void *);
80
81extern void init_IRQ(void);
82extern void sock_init(void);
83extern void fork_init(unsigned long);
84extern void mca_init(void);
85extern void sbus_init(void);
86extern void sysctl_init(void);
87extern void signals_init(void);
88extern void buffer_init(void);
89extern void pidhash_init(void);
90extern void pidmap_init(void);
91extern void prio_tree_init(void);
92extern void radix_tree_init(void);
93extern void free_initmem(void);
94extern void populate_rootfs(void);
95extern void driver_init(void);
96extern void prepare_namespace(void);
97#ifdef CONFIG_ACPI
98extern void acpi_early_init(void);
99#else
100static inline void acpi_early_init(void) { }
101#endif
102
103#ifdef CONFIG_TC
104extern void tc_init(void);
105#endif
106
107enum system_states system_state;
108EXPORT_SYMBOL(system_state);
109
110/*
111 * Boot command-line arguments
112 */
113#define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
114#define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
115
116extern void time_init(void);
117/* Default late time init is NULL. archs can override this later. */
118void (*late_time_init)(void);
119extern void softirq_init(void);
120
121/* Untouched command line (eg. for /proc) saved by arch-specific code. */
122char saved_command_line[COMMAND_LINE_SIZE];
123
124static char *execute_command;
125
126/* Setup configured maximum number of CPUs to activate */
127static unsigned int max_cpus = NR_CPUS;
128
129/*
130 * Setup routine for controlling SMP activation
131 *
132 * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
133 * activation entirely (the MPS table probe still happens, though).
134 *
135 * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
136 * greater than 0, limits the maximum number of CPUs activated in
137 * SMP mode to <NUM>.
138 */
139static int __init nosmp(char *str)
140{
141 max_cpus = 0;
142 return 1;
143}
144
145__setup("nosmp", nosmp);
146
147static int __init maxcpus(char *str)
148{
149 get_option(&str, &max_cpus);
150 return 1;
151}
152
153__setup("maxcpus=", maxcpus);
154
155static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
156char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
157static const char *panic_later, *panic_param;
158
159extern struct obs_kernel_param __setup_start[], __setup_end[];
160
161static int __init obsolete_checksetup(char *line)
162{
163 struct obs_kernel_param *p;
164
165 p = __setup_start;
166 do {
167 int n = strlen(p->str);
168 if (!strncmp(line, p->str, n)) {
169 if (p->early) {
170 /* Already done in parse_early_param? (Needs
171 * exact match on param part) */
172 if (line[n] == '\0' || line[n] == '=')
173 return 1;
174 } else if (!p->setup_func) {
175 printk(KERN_WARNING "Parameter %s is obsolete,"
176 " ignored\n", p->str);
177 return 1;
178 } else if (p->setup_func(line + n))
179 return 1;
180 }
181 p++;
182 } while (p < __setup_end);
183 return 0;
184}
185
186/*
187 * This should be approx 2 Bo*oMips to start (note initial shift), and will
188 * still work even if initially too large, it will just take slightly longer
189 */
190unsigned long loops_per_jiffy = (1<<12);
191
192EXPORT_SYMBOL(loops_per_jiffy);
193
194static int __init debug_kernel(char *str)
195{
196 if (*str)
197 return 0;
198 console_loglevel = 10;
199 return 1;
200}
201
202static int __init quiet_kernel(char *str)
203{
204 if (*str)
205 return 0;
206 console_loglevel = 4;
207 return 1;
208}
209
210__setup("debug", debug_kernel);
211__setup("quiet", quiet_kernel);
212
213static int __init loglevel(char *str)
214{
215 get_option(&str, &console_loglevel);
216 return 1;
217}
218
219__setup("loglevel=", loglevel);
220
221/*
222 * Unknown boot options get handed to init, unless they look like
223 * failed parameters
224 */
225static int __init unknown_bootoption(char *param, char *val)
226{
227 /* Change NUL term back to "=", to make "param" the whole string. */
228 if (val) {
229 /* param=val or param="val"? */
230 if (val == param+strlen(param)+1)
231 val[-1] = '=';
232 else if (val == param+strlen(param)+2) {
233 val[-2] = '=';
234 memmove(val-1, val, strlen(val)+1);
235 val--;
236 } else
237 BUG();
238 }
239
240 /* Handle obsolete-style parameters */
241 if (obsolete_checksetup(param))
242 return 0;
243
244 /*
245 * Preemptive maintenance for "why didn't my mispelled command
246 * line work?"
247 */
248 if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
249 printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
250 return 0;
251 }
252
253 if (panic_later)
254 return 0;
255
256 if (val) {
257 /* Environment option */
258 unsigned int i;
259 for (i = 0; envp_init[i]; i++) {
260 if (i == MAX_INIT_ENVS) {
261 panic_later = "Too many boot env vars at `%s'";
262 panic_param = param;
263 }
264 if (!strncmp(param, envp_init[i], val - param))
265 break;
266 }
267 envp_init[i] = param;
268 } else {
269 /* Command line option */
270 unsigned int i;
271 for (i = 0; argv_init[i]; i++) {
272 if (i == MAX_INIT_ARGS) {
273 panic_later = "Too many boot init vars at `%s'";
274 panic_param = param;
275 }
276 }
277 argv_init[i] = param;
278 }
279 return 0;
280}
281
282static int __init init_setup(char *str)
283{
284 unsigned int i;
285
286 execute_command = str;
287 /*
288 * In case LILO is going to boot us with default command line,
289 * it prepends "auto" before the whole cmdline which makes
290 * the shell think it should execute a script with such name.
291 * So we ignore all arguments entered _before_ init=... [MJ]
292 */
293 for (i = 1; i < MAX_INIT_ARGS; i++)
294 argv_init[i] = NULL;
295 return 1;
296}
297__setup("init=", init_setup);
298
299extern void setup_arch(char **);
300
301#ifndef CONFIG_SMP
302
303#ifdef CONFIG_X86_LOCAL_APIC
304static void __init smp_init(void)
305{
306 APIC_init_uniprocessor();
307}
308#else
309#define smp_init() do { } while (0)
310#endif
311
312static inline void setup_per_cpu_areas(void) { }
313static inline void smp_prepare_cpus(unsigned int maxcpus) { }
314
315#else
316
317#ifdef __GENERIC_PER_CPU
318unsigned long __per_cpu_offset[NR_CPUS];
319
320EXPORT_SYMBOL(__per_cpu_offset);
321
322static void __init setup_per_cpu_areas(void)
323{
324 unsigned long size, i;
325 char *ptr;
326 /* Created by linker magic */
327 extern char __per_cpu_start[], __per_cpu_end[];
328
329 /* Copy section for each CPU (we discard the original) */
330 size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
331#ifdef CONFIG_MODULES
332 if (size < PERCPU_ENOUGH_ROOM)
333 size = PERCPU_ENOUGH_ROOM;
334#endif
335
336 ptr = alloc_bootmem(size * NR_CPUS);
337
338 for (i = 0; i < NR_CPUS; i++, ptr += size) {
339 __per_cpu_offset[i] = ptr - __per_cpu_start;
340 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
341 }
342}
343#endif /* !__GENERIC_PER_CPU */
344
345/* Called by boot processor to activate the rest. */
346static void __init smp_init(void)
347{
348 unsigned int i;
349
350 /* FIXME: This should be done in userspace --RR */
351 for_each_present_cpu(i) {
352 if (num_online_cpus() >= max_cpus)
353 break;
354 if (!cpu_online(i))
355 cpu_up(i);
356 }
357
358 /* Any cleanup work */
359 printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
360 smp_cpus_done(max_cpus);
361#if 0
362 /* Get other processors into their bootup holding patterns. */
363
364 smp_commence();
365#endif
366}
367
368#endif
369
370/*
371 * We need to finalize in a non-__init function or else race conditions
372 * between the root thread and the init thread may cause start_kernel to
373 * be reaped by free_initmem before the root thread has proceeded to
374 * cpu_idle.
375 *
376 * gcc-3.4 accidentally inlines this function, so use noinline.
377 */
378
379static void noinline rest_init(void)
380 __releases(kernel_lock)
381{
382 kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
383 numa_default_policy();
384 unlock_kernel();
385 preempt_enable_no_resched();
386 cpu_idle();
387}
388
389/* Check for early params. */
390static int __init do_early_param(char *param, char *val)
391{
392 struct obs_kernel_param *p;
393
394 for (p = __setup_start; p < __setup_end; p++) {
395 if (p->early && strcmp(param, p->str) == 0) {
396 if (p->setup_func(val) != 0)
397 printk(KERN_WARNING
398 "Malformed early option '%s'\n", param);
399 }
400 }
401 /* We accept everything at this stage. */
402 return 0;
403}
404
405/* Arch code calls this early on, or if not, just before other parsing. */
406void __init parse_early_param(void)
407{
408 static __initdata int done = 0;
409 static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
410
411 if (done)
412 return;
413
414 /* All fall through to do_early_param. */
415 strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE);
416 parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
417 done = 1;
418}
419
420/*
421 * Activate the first processor.
422 */
423
424asmlinkage void __init start_kernel(void)
425{
426 char * command_line;
427 extern struct kernel_param __start___param[], __stop___param[];
428/*
429 * Interrupts are still disabled. Do necessary setups, then
430 * enable them
431 */
432 lock_kernel();
433 page_address_init();
434 printk(KERN_NOTICE);
435 printk(linux_banner);
436 setup_arch(&command_line);
437 setup_per_cpu_areas();
438
439 /*
440 * Mark the boot cpu "online" so that it can call console drivers in
441 * printk() and can access its per-cpu storage.
442 */
443 smp_prepare_boot_cpu();
444
445 /*
446 * Set up the scheduler prior starting any interrupts (such as the
447 * timer interrupt). Full topology setup happens at smp_init()
448 * time - but meanwhile we still have a functioning scheduler.
449 */
450 sched_init();
451 /*
452 * Disable preemption - early bootup scheduling is extremely
453 * fragile until we cpu_idle() for the first time.
454 */
455 preempt_disable();
456 build_all_zonelists();
457 page_alloc_init();
458 printk(KERN_NOTICE "Kernel command line: %s\n", saved_command_line);
459 parse_early_param();
460 parse_args("Booting kernel", command_line, __start___param,
461 __stop___param - __start___param,
462 &unknown_bootoption);
463 sort_main_extable();
464 trap_init();
465 rcu_init();
466 init_IRQ();
467 pidhash_init();
468 init_timers();
469 softirq_init();
470 time_init();
471
472 /*
473 * HACK ALERT! This is early. We're enabling the console before
474 * we've done PCI setups etc, and console_init() must be aware of
475 * this. But we do want output early, in case something goes wrong.
476 */
477 console_init();
478 if (panic_later)
479 panic(panic_later, panic_param);
480 profile_init();
481 local_irq_enable();
482#ifdef CONFIG_BLK_DEV_INITRD
483 if (initrd_start && !initrd_below_start_ok &&
484 initrd_start < min_low_pfn << PAGE_SHIFT) {
485 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
486 "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
487 initrd_start = 0;
488 }
489#endif
490 vfs_caches_init_early();
491 mem_init();
492 kmem_cache_init();
493 numa_policy_init();
494 if (late_time_init)
495 late_time_init();
496 calibrate_delay();
497 pidmap_init();
498 pgtable_cache_init();
499 prio_tree_init();
500 anon_vma_init();
501#ifdef CONFIG_X86
502 if (efi_enabled)
503 efi_enter_virtual_mode();
504#endif
505 fork_init(num_physpages);
506 proc_caches_init();
507 buffer_init();
508 unnamed_dev_init();
509 key_init();
510 security_init();
511 vfs_caches_init(num_physpages);
512 radix_tree_init();
513 signals_init();
514 /* rootfs populating might need page-writeback */
515 page_writeback_init();
516#ifdef CONFIG_PROC_FS
517 proc_root_init();
518#endif
519 cpuset_init();
520
521 check_bugs();
522
523 acpi_early_init(); /* before LAPIC and SMP init */
524
525 /* Do the rest non-__init'ed, we're now alive */
526 rest_init();
527}
528
529static int __initdata initcall_debug;
530
531static int __init initcall_debug_setup(char *str)
532{
533 initcall_debug = 1;
534 return 1;
535}
536__setup("initcall_debug", initcall_debug_setup);
537
538struct task_struct *child_reaper = &init_task;
539
540extern initcall_t __initcall_start[], __initcall_end[];
541
542static void __init do_initcalls(void)
543{
544 initcall_t *call;
545 int count = preempt_count();
546
547 for (call = __initcall_start; call < __initcall_end; call++) {
548 char *msg;
549
550 if (initcall_debug) {
551 printk(KERN_DEBUG "Calling initcall 0x%p", *call);
552 print_fn_descriptor_symbol(": %s()", (unsigned long) *call);
553 printk("\n");
554 }
555
556 (*call)();
557
558 msg = NULL;
559 if (preempt_count() != count) {
560 msg = "preemption imbalance";
561 preempt_count() = count;
562 }
563 if (irqs_disabled()) {
564 msg = "disabled interrupts";
565 local_irq_enable();
566 }
567 if (msg) {
568 printk(KERN_WARNING "error in initcall at 0x%p: "
569 "returned with %s\n", *call, msg);
570 }
571 }
572
573 /* Make sure there is no pending stuff from the initcall sequence */
574 flush_scheduled_work();
575}
576
577/*
578 * Ok, the machine is now initialized. None of the devices
579 * have been touched yet, but the CPU subsystem is up and
580 * running, and memory and process management works.
581 *
582 * Now we can finally start doing some real work..
583 */
584static void __init do_basic_setup(void)
585{
586 /* drivers will send hotplug events */
587 init_workqueues();
588 usermodehelper_init();
589 driver_init();
590
591#ifdef CONFIG_SYSCTL
592 sysctl_init();
593#endif
594
595 /* Networking initialization needs a process context */
596 sock_init();
597
598 do_initcalls();
599}
600
601static void do_pre_smp_initcalls(void)
602{
603 extern int spawn_ksoftirqd(void);
604#ifdef CONFIG_SMP
605 extern int migration_init(void);
606
607 migration_init();
608#endif
609 spawn_ksoftirqd();
610}
611
612static void run_init_process(char *init_filename)
613{
614 argv_init[0] = init_filename;
615 execve(init_filename, argv_init, envp_init);
616}
617
618static inline void fixup_cpu_present_map(void)
619{
620#ifdef CONFIG_SMP
621 int i;
622
623 /*
624 * If arch is not hotplug ready and did not populate
625 * cpu_present_map, just make cpu_present_map same as cpu_possible_map
626 * for other cpu bringup code to function as normal. e.g smp_init() etc.
627 */
628 if (cpus_empty(cpu_present_map)) {
629 for_each_cpu(i) {
630 cpu_set(i, cpu_present_map);
631 }
632 }
633#endif
634}
635
636static int init(void * unused)
637{
638 lock_kernel();
639 /*
640 * init can run on any cpu.
641 */
642 set_cpus_allowed(current, CPU_MASK_ALL);
643 /*
644 * Tell the world that we're going to be the grim
645 * reaper of innocent orphaned children.
646 *
647 * We don't want people to have to make incorrect
648 * assumptions about where in the task array this
649 * can be found.
650 */
651 child_reaper = current;
652
653 /* Sets up cpus_possible() */
654 smp_prepare_cpus(max_cpus);
655
656 do_pre_smp_initcalls();
657
658 fixup_cpu_present_map();
659 smp_init();
660 sched_init_smp();
661
662 cpuset_init_smp();
663
664 /*
665 * Do this before initcalls, because some drivers want to access
666 * firmware files.
667 */
668 populate_rootfs();
669
670 do_basic_setup();
671
672 /*
673 * check if there is an early userspace init. If yes, let it do all
674 * the work
675 */
676 if (sys_access((const char __user *) "/init", 0) == 0)
677 execute_command = "/init";
678 else
679 prepare_namespace();
680
681 /*
682 * Ok, we have completed the initial bootup, and
683 * we're essentially up and running. Get rid of the
684 * initmem segments and start the user-mode stuff..
685 */
686 free_initmem();
687 unlock_kernel();
688 system_state = SYSTEM_RUNNING;
689 numa_default_policy();
690
691 if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
692 printk(KERN_WARNING "Warning: unable to open an initial console.\n");
693
694 (void) sys_dup(0);
695 (void) sys_dup(0);
696
697 /*
698 * We try each of these until one succeeds.
699 *
700 * The Bourne shell can be used instead of init if we are
701 * trying to recover a really broken machine.
702 */
703
704 if (execute_command)
705 run_init_process(execute_command);
706
707 run_init_process("/sbin/init");
708 run_init_process("/etc/init");
709 run_init_process("/bin/init");
710 run_init_process("/bin/sh");
711
712 panic("No init found. Try passing init= option to kernel.");
713}
diff --git a/init/version.c b/init/version.c
new file mode 100644
index 00000000000..3ddc3ceec2f
--- /dev/null
+++ b/init/version.c
@@ -0,0 +1,33 @@
1/*
2 * linux/init/version.c
3 *
4 * Copyright (C) 1992 Theodore Ts'o
5 *
6 * May be freely distributed as part of Linux.
7 */
8
9#include <linux/compile.h>
10#include <linux/module.h>
11#include <linux/uts.h>
12#include <linux/utsname.h>
13#include <linux/version.h>
14
15#define version(a) Version_ ## a
16#define version_string(a) version(a)
17
18int version_string(LINUX_VERSION_CODE);
19
20struct new_utsname system_utsname = {
21 .sysname = UTS_SYSNAME,
22 .nodename = UTS_NODENAME,
23 .release = UTS_RELEASE,
24 .version = UTS_VERSION,
25 .machine = UTS_MACHINE,
26 .domainname = UTS_DOMAINNAME,
27};
28
29EXPORT_SYMBOL(system_utsname);
30
31const char linux_banner[] =
32 "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
33 LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";