1 Index: linux-2.6.31.5/arch/x86/kernel/vmlinux.lds.S
2 ===================================================================
3 --- linux-2.6.31.5.orig/arch/x86/kernel/vmlinux.lds.S 2009-10-23 00:57:56.000000000 +0200
4 +++ linux-2.6.31.5/arch/x86/kernel/vmlinux.lds.S 2009-11-07 14:31:54.000000000 +0100
9 + .root_initcall.init : AT(ADDR(.root_initcall.init) - LOAD_OFFSET) {
10 + __root_initcall_start = .;
12 + __root_initcall_end = .;
15 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
16 __con_initcall_start = .;
18 Index: linux-2.6.31.5/drivers/mtd/devices/block2mtd.c
19 ===================================================================
20 --- linux-2.6.31.5.orig/drivers/mtd/devices/block2mtd.c 2009-11-07 14:30:57.000000000 +0100
21 +++ linux-2.6.31.5/drivers/mtd/devices/block2mtd.c 2009-11-07 14:31:19.000000000 +0100
23 #include <linux/buffer_head.h>
24 #include <linux/mutex.h>
25 #include <linux/mount.h>
26 +#include <linux/list.h>
27 +#include <linux/delay.h>
29 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
30 #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
33 + struct list_head list;
37 +static LIST_HEAD(retry_list);
39 /* Info for the block device */
40 struct block2mtd_dev {
45 +static int block2mtd_setup2(const char *val);
47 /* Static info about the MTD, used in cleanup_module */
48 static LIST_HEAD(blkmtd_device_list);
50 +static int add_retry(const char *val) {
51 + struct retry *r = kmalloc(sizeof(struct retry), GFP_KERNEL);
53 + INIT_LIST_HEAD(&r->list);
55 + list_add(&r->list, &retry_list);
60 +static int __init process_retries(void) {
61 + struct list_head *p, *tmp;
63 + list_for_each_safe(p, tmp, &retry_list) {
64 + struct retry *r = list_entry(p, struct retry, list);
65 + block2mtd_setup2(r->val);
72 +rootfs_initcall(process_retries);
74 static struct page *page_read(struct address_space *mapping, int index)
77 if (token[2] && (strlen(token[2]) + 1 > 80))
78 parse_err("mtd device name too long");
80 - add_device(name, erase_size, token[2]);
81 + if (add_device(name, erase_size, token[2]) == NULL) {
87 Index: linux-2.6.31.5/include/asm-generic/vmlinux.lds.h
88 ===================================================================
89 --- linux-2.6.31.5.orig/include/asm-generic/vmlinux.lds.h 2009-11-07 14:30:57.000000000 +0100
90 +++ linux-2.6.31.5/include/asm-generic/vmlinux.lds.h 2009-11-07 14:31:19.000000000 +0100
95 - *(.initcallrootfs.init) \
101 +#define INITCALLS_ROOT \
102 + *(.initcallrootfs.init)
105 VMLINUX_SYMBOL(__initcall_start) = .; \
107 Index: linux-2.6.31.5/init/do_mounts.c
108 ===================================================================
109 --- linux-2.6.31.5.orig/init/do_mounts.c 2009-10-23 00:57:56.000000000 +0200
110 +++ linux-2.6.31.5/init/do_mounts.c 2009-11-07 14:31:19.000000000 +0100
115 -static unsigned int __initdata root_delay;
116 -static int __init root_delay_setup(char *str)
118 - root_delay = simple_strtoul(str, NULL, 0);
122 __setup("rootflags=", root_data_setup);
123 __setup("rootfstype=", fs_names_setup);
124 -__setup("rootdelay=", root_delay_setup);
126 static void __init get_fs_names(char *page)
133 - printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
135 - ssleep(root_delay);
139 - * wait for the known devices to complete their probing
141 - * Note: this is a potential source of long boot delays.
142 - * For example, it is not atypical to wait 5 seconds here
143 - * for the touchpad of a laptop to initialize.
145 - wait_for_device_probe();
149 if (saved_root_name[0]) {
150 root_device_name = saved_root_name;
151 if (!strncmp(root_device_name, "mtd", 3) ||
152 Index: linux-2.6.31.5/init/main.c
153 ===================================================================
154 --- linux-2.6.31.5.orig/init/main.c 2009-11-07 14:30:59.000000000 +0100
155 +++ linux-2.6.31.5/init/main.c 2009-11-07 14:31:19.000000000 +0100
157 #ifdef CONFIG_X86_LOCAL_APIC
160 +#include "do_mounts.h"
162 static int kernel_init(void *);
164 @@ -784,12 +785,13 @@
167 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
168 +extern initcall_t __root_initcall_start[], __root_initcall_end[];
170 -static void __init do_initcalls(void)
171 +static void __init do_initcalls(initcall_t *start, initcall_t *end)
175 - for (call = __early_initcall_end; call < __initcall_end; call++)
176 + for (call = start; call < end; call++)
177 do_one_initcall(*call);
179 /* Make sure there is no pending stuff from the initcall sequence */
185 + do_initcalls(__early_initcall_end, __initcall_end);
188 static void __init do_pre_smp_initcalls(void)
190 panic("No init found. Try passing init= option to kernel.");
193 +static unsigned int __initdata root_delay;
194 +static int __init root_delay_setup(char *str)
196 + root_delay = simple_strtoul(str, NULL, 0);
199 +__setup("rootdelay=", root_delay_setup);
200 static int __init kernel_init(void * unused)
205 if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
206 ramdisk_execute_command = NULL;
207 - prepare_namespace();
209 + printk(KERN_INFO "Waiting %desc before mounting root device...\n",
211 + ssleep(root_delay);
213 + while (driver_probe_done() != 0)
216 + do_initcalls(__root_initcall_start, __root_initcall_end);
217 + prepare_namespace();