From fae1ded3a78230241aee97bc6415a1af4f5b6c69 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:49:43 -0700 Subject: [PATCH] --- yaml --- r: 116388 b: refs/heads/master c: 3ddfda11861d305b02ed810b522dcf48b74ca808 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/asm-generic/vmlinux.lds.h | 7 +++++++ trunk/include/linux/init.h | 23 +++++++++++++++++++++++ trunk/init/main.c | 24 ++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 26e30274a196..bc6de36751b7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 38395738f581ce9417402f28774a8c4650264a00 +refs/heads/master: 3ddfda11861d305b02ed810b522dcf48b74ca808 diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 7440a0dceddb..7881406c03ec 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -210,6 +210,13 @@ * All archs are supposed to use RO_DATA() */ #define RODATA RO_DATA(4096) +#define DYN_ARRAY_INIT(align) \ + . = ALIGN((align)); \ + .dyn_array.init : AT(ADDR(.dyn_array.init) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__dyn_array_start) = .; \ + *(.dyn_array.init) \ + VMLINUX_SYMBOL(__dyn_array_end) = .; \ + } #define SECURITY_INIT \ .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__security_initcall_start) = .; \ diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index 93538b696e3d..cf9fa7f174af 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -246,6 +246,29 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); + +struct dyn_array { + void **name; + unsigned long size; + unsigned int *nr; + unsigned long align; + void (*init_work)(void *); +}; +extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; + +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __dyn_array_##nameX __initdata = \ + { .name = (void **)&nameX,\ + .size = sizeX,\ + .nr = &nrX,\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".dyn_array.init"))) = \ + &__dyn_array_##nameX + +extern void pre_alloc_dyn_array(void); #endif /* __ASSEMBLY__ */ /** diff --git a/trunk/init/main.c b/trunk/init/main.c index 27f6bf6108e9..638d3a786412 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -536,6 +536,29 @@ void __init __weak thread_info_cache_init(void) { } +void pre_alloc_dyn_array(void) +{ +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned long size, phys = 0; + struct dyn_array **daa; + + for (daa = __dyn_array_start ; daa < __dyn_array_end; daa++) { + struct dyn_array *da = *daa; + + size = da->size * (*da->nr); + print_fn_descriptor_symbol("dyna_array %s ", da->name); + printk(KERN_CONT "size:%#lx nr:%d align:%#lx", + da->size, *da->nr, da->align); + *da->name = __alloc_bootmem(size, da->align, phys); + phys = virt_to_phys(*da->name); + printk(KERN_CONT " ==> [%#lx - %#lx]\n", phys, phys + size); + + if (da->init_work) + da->init_work(da); + } +#endif +} + asmlinkage void __init start_kernel(void) { char * command_line; @@ -567,6 +590,7 @@ asmlinkage void __init start_kernel(void) printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); + pre_alloc_dyn_array(); mm_init_owner(&init_mm, &init_task); setup_command_line(command_line); unwind_setup();