diff options
Diffstat (limited to 'uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c')
-rw-r--r-- | uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c | 161 |
1 files changed, 62 insertions, 99 deletions
diff --git a/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c b/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c index 05af4f1..47e475d 100644 --- a/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c +++ b/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c @@ -56,6 +56,8 @@ extern void _netarm_led_blink(void); #endif extern void paging_init(struct meminfo *, struct machine_desc *desc); +extern void convert_to_tag_list(struct tag *tags); +extern void squash_mem_tags(struct tag *tag); extern void bootmem_init(struct meminfo *); extern void reboot_setup(char *str); extern unsigned long long memparse(char *ptr, char **retptr); @@ -347,6 +349,8 @@ static int __init parse_tag_core(const struct tag *tag) return 0; } +__tagtable(ATAG_CORE, parse_tag_core); + static int __init parse_tag_mem32(const struct tag *tag) { if (meminfo.nr_banks >= NR_BANKS) { @@ -363,6 +367,8 @@ static int __init parse_tag_mem32(const struct tag *tag) return 0; } +__tagtable(ATAG_MEM, parse_tag_mem32); + static int __init parse_tag_videotext(const struct tag *tag) { screen_info.orig_x = tag->u.videotext.x; @@ -377,6 +383,8 @@ static int __init parse_tag_videotext(const struct tag *tag) return 0; } +__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); + static int __init parse_tag_ramdisk(const struct tag *tag) { setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, @@ -385,12 +393,16 @@ static int __init parse_tag_ramdisk(const struct tag *tag) return 0; } +__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); + static int __init parse_tag_initrd(const struct tag *tag) { setup_initrd(tag->u.initrd.start, tag->u.initrd.size); return 0; } +__tagtable(ATAG_INITRD, parse_tag_initrd); + static int __init parse_tag_serialnr(const struct tag *tag) { system_serial_low = tag->u.serialnr.low; @@ -398,12 +410,16 @@ static int __init parse_tag_serialnr(const struct tag *tag) return 0; } +__tagtable(ATAG_SERIAL, parse_tag_serialnr); + static int __init parse_tag_revision(const struct tag *tag) { system_rev = tag->u.revision.rev; return 0; } +__tagtable(ATAG_REVISION, parse_tag_revision); + static int __init parse_tag_cmdline(const struct tag *tag) { strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); @@ -411,110 +427,57 @@ static int __init parse_tag_cmdline(const struct tag *tag) return 0; } -/* - * This is the core tag table; these are the tags - * that we recognise for any machine type. - */ -static const struct tagtable core_tagtable[] __init = { - { ATAG_CORE, parse_tag_core }, - { ATAG_MEM, parse_tag_mem32 }, - { ATAG_VIDEOTEXT, parse_tag_videotext }, - { ATAG_RAMDISK, parse_tag_ramdisk }, - { ATAG_INITRD, parse_tag_initrd }, - { ATAG_SERIAL, parse_tag_serialnr }, - { ATAG_REVISION, parse_tag_revision }, - { ATAG_CMDLINE, parse_tag_cmdline } -}; +__tagtable(ATAG_CMDLINE, parse_tag_cmdline); /* * Scan one tag table for this tag, and call its parse function. + * The tag table is built by the linker from all the __tagtable + * declarations. */ -static int __init -parse_tag(const struct tagtable *tbl, int size, const struct tag *t) +static int __init parse_tag(const struct tag *tag) { - int i; + extern struct tagtable __tagtable_begin, __tagtable_end; + struct tagtable *t; - for (i = 0; i < size; i++, tbl++) - if (t->hdr.tag == tbl->tag) { - tbl->parse(t); + for (t = &__tagtable_begin; t < &__tagtable_end; t++) + if (tag->hdr.tag == t->tag) { + t->parse(tag); break; } - return i < size; + return t < &__tagtable_end; } /* * Parse all tags in the list, checking both the global and architecture * specific tag tables. */ -static void __init -parse_tags(const struct tagtable *tbl, int size, const struct tag *t) +static void __init parse_tags(const struct tag *t) { - /* - * The tag list is terminated with a zero-sized tag. Size is - * defined to be in units of 32-bit quantities. - */ - for (; t->hdr.size; t = (struct tag *)((u32 *)t + t->hdr.size)) { - if (parse_tag(core_tagtable, ARRAY_SIZE(core_tagtable), t)) - continue; - - if (tbl && parse_tag(tbl, size, t)) - continue; - - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", t->hdr.tag); - } + for (; t->hdr.size; t = tag_next(t)) + if (!parse_tag(t)) + printk(KERN_WARNING + "Ignoring unrecognised tag 0x%08x\n", + t->hdr.tag); } -static void __init parse_params(struct param_struct *params) -{ - if (params->u1.s.page_size != PAGE_SIZE) { - printk(KERN_WARNING "Warning: bad configuration page, " - "trying to continue\n"); - return; - } - - ROOT_DEV = to_kdev_t(params->u1.s.rootdev); - system_rev = params->u1.s.system_rev; - system_serial_low = params->u1.s.system_serial_low; - system_serial_high = params->u1.s.system_serial_high; - - if (params->u1.s.mem_fclk_21285 > 0) - mem_fclk_21285 = params->u1.s.mem_fclk_21285; - - setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0, - (params->u1.s.flags & FLAG_RDPROMPT) == 0, - params->u1.s.rd_start, - params->u1.s.ramdisk_size); - - setup_initrd(params->u1.s.initrd_start, - params->u1.s.initrd_size); - - if (!(params->u1.s.flags & FLAG_READONLY)) - root_mountflags &= ~MS_RDONLY; - - strncpy(default_command_line, params->commandline, COMMAND_LINE_SIZE); - default_command_line[COMMAND_LINE_SIZE - 1] = '\0'; - - if (meminfo.nr_banks == 0) { - meminfo.nr_banks = 1; - meminfo.bank[0].start = PHYS_OFFSET; - meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT; - } -} - - -/* - * Tell the kernel about any console devices we may have, the user - * can use bootargs select which one they get. The default will be - * the console you register first. - */ - - +static struct init_tags { + struct tag_header hdr1; + struct tag_core core; + struct tag_header hdr2; + struct tag_mem32 mem; + struct tag_header hdr3; +} init_tags __initdata = { + { tag_size(tag_core), ATAG_CORE }, + { 1, PAGE_SIZE, 0xff }, + { tag_size(tag_mem32), ATAG_MEM }, + { MEM_SIZE, PHYS_OFFSET }, + { 0, ATAG_NONE } +}; void __init setup_arch(char **cmdline_p) { - struct param_struct *params = NULL; + struct tag *tags = (struct tag *)&init_tags; struct machine_desc *mdesc; char *from = default_command_line; int bootmap_size; @@ -533,28 +496,28 @@ void __init setup_arch(char **cmdline_p) reboot_setup("s"); if (mdesc->param_offset) - params = (struct param_struct*) - (phys_to_virt(mdesc->param_offset)); + tags = phys_to_virt(mdesc->param_offset); /* * Do the machine-specific fixups before we parse the * parameters or tags. */ if (mdesc->fixup) - mdesc->fixup(mdesc, params, &from, &meminfo); - - if (params) { - struct tag *tag = (struct tag *)params; - - /* - * Is the first tag the CORE tag? This differentiates - * between the tag list and the parameter table. - */ - if (tag->hdr.tag == ATAG_CORE) - parse_tags(mdesc->tagtable, mdesc->tagsize, tag); - else - parse_params(params); - } + mdesc->fixup(mdesc, (struct param_struct *)tags, + &from, &meminfo); + + /* + * If we have the old style parameters, convert them to + * a tag list. + */ + if (tags->hdr.tag != ATAG_CORE) + convert_to_tag_list(tags); + + if (tags->hdr.tag == ATAG_CORE) { + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); + parse_tags(tags); + } if (meminfo.nr_banks == 0) { meminfo.nr_banks = 1; |