~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/kernel/atags_parse.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Tag parsing.
  3  *
  4  * Copyright (C) 1995-2001 Russell King
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 as
  8  * published by the Free Software Foundation.
  9  */
 10 
 11 /*
 12  * This is the traditional way of passing data to the kernel at boot time.  Rather
 13  * than passing a fixed inflexible structure to the kernel, we pass a list
 14  * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
 15  * tag for the list to be recognised (to distinguish the tagged list from
 16  * a param_struct).  The list is terminated with a zero-length tag (this tag
 17  * is not parsed in any way).
 18  */
 19 
 20 #include <linux/init.h>
 21 #include <linux/kernel.h>
 22 #include <linux/fs.h>
 23 #include <linux/root_dev.h>
 24 #include <linux/screen_info.h>
 25 
 26 #include <asm/setup.h>
 27 #include <asm/system_info.h>
 28 #include <asm/page.h>
 29 #include <asm/mach/arch.h>
 30 
 31 #include "atags.h"
 32 
 33 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 34 
 35 #ifndef MEM_SIZE
 36 #define MEM_SIZE        (16*1024*1024)
 37 #endif
 38 
 39 static struct {
 40         struct tag_header hdr1;
 41         struct tag_core   core;
 42         struct tag_header hdr2;
 43         struct tag_mem32  mem;
 44         struct tag_header hdr3;
 45 } default_tags __initdata = {
 46         { tag_size(tag_core), ATAG_CORE },
 47         { 1, PAGE_SIZE, 0xff },
 48         { tag_size(tag_mem32), ATAG_MEM },
 49         { MEM_SIZE },
 50         { 0, ATAG_NONE }
 51 };
 52 
 53 static int __init parse_tag_core(const struct tag *tag)
 54 {
 55         if (tag->hdr.size > 2) {
 56                 if ((tag->u.core.flags & 1) == 0)
 57                         root_mountflags &= ~MS_RDONLY;
 58                 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
 59         }
 60         return 0;
 61 }
 62 
 63 __tagtable(ATAG_CORE, parse_tag_core);
 64 
 65 static int __init parse_tag_mem32(const struct tag *tag)
 66 {
 67         return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
 68 }
 69 
 70 __tagtable(ATAG_MEM, parse_tag_mem32);
 71 
 72 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 73 static int __init parse_tag_videotext(const struct tag *tag)
 74 {
 75         screen_info.orig_x            = tag->u.videotext.x;
 76         screen_info.orig_y            = tag->u.videotext.y;
 77         screen_info.orig_video_page   = tag->u.videotext.video_page;
 78         screen_info.orig_video_mode   = tag->u.videotext.video_mode;
 79         screen_info.orig_video_cols   = tag->u.videotext.video_cols;
 80         screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
 81         screen_info.orig_video_lines  = tag->u.videotext.video_lines;
 82         screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
 83         screen_info.orig_video_points = tag->u.videotext.video_points;
 84         return 0;
 85 }
 86 
 87 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
 88 #endif
 89 
 90 #ifdef CONFIG_BLK_DEV_RAM
 91 static int __init parse_tag_ramdisk(const struct tag *tag)
 92 {
 93         extern int rd_size, rd_image_start, rd_prompt, rd_doload;
 94 
 95         rd_image_start = tag->u.ramdisk.start;
 96         rd_doload = (tag->u.ramdisk.flags & 1) == 0;
 97         rd_prompt = (tag->u.ramdisk.flags & 2) == 0;
 98 
 99         if (tag->u.ramdisk.size)
100                 rd_size = tag->u.ramdisk.size;
101 
102         return 0;
103 }
104 
105 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
106 #endif
107 
108 static int __init parse_tag_serialnr(const struct tag *tag)
109 {
110         system_serial_low = tag->u.serialnr.low;
111         system_serial_high = tag->u.serialnr.high;
112         return 0;
113 }
114 
115 __tagtable(ATAG_SERIAL, parse_tag_serialnr);
116 
117 static int __init parse_tag_revision(const struct tag *tag)
118 {
119         system_rev = tag->u.revision.rev;
120         return 0;
121 }
122 
123 __tagtable(ATAG_REVISION, parse_tag_revision);
124 
125 static int __init parse_tag_cmdline(const struct tag *tag)
126 {
127 #if defined(CONFIG_CMDLINE_EXTEND)
128         strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
129         strlcat(default_command_line, tag->u.cmdline.cmdline,
130                 COMMAND_LINE_SIZE);
131 #elif defined(CONFIG_CMDLINE_FORCE)
132         pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
133 #else
134         strlcpy(default_command_line, tag->u.cmdline.cmdline,
135                 COMMAND_LINE_SIZE);
136 #endif
137         return 0;
138 }
139 
140 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
141 
142 /*
143  * Scan the tag table for this tag, and call its parse function.
144  * The tag table is built by the linker from all the __tagtable
145  * declarations.
146  */
147 static int __init parse_tag(const struct tag *tag)
148 {
149         extern struct tagtable __tagtable_begin, __tagtable_end;
150         struct tagtable *t;
151 
152         for (t = &__tagtable_begin; t < &__tagtable_end; t++)
153                 if (tag->hdr.tag == t->tag) {
154                         t->parse(tag);
155                         break;
156                 }
157 
158         return t < &__tagtable_end;
159 }
160 
161 /*
162  * Parse all tags in the list, checking both the global and architecture
163  * specific tag tables.
164  */
165 static void __init parse_tags(const struct tag *t)
166 {
167         for (; t->hdr.size; t = tag_next(t))
168                 if (!parse_tag(t))
169                         printk(KERN_WARNING
170                                 "Ignoring unrecognised tag 0x%08x\n",
171                                 t->hdr.tag);
172 }
173 
174 static void __init squash_mem_tags(struct tag *tag)
175 {
176         for (; tag->hdr.size; tag = tag_next(tag))
177                 if (tag->hdr.tag == ATAG_MEM)
178                         tag->hdr.tag = ATAG_NONE;
179 }
180 
181 struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer,
182                                                 unsigned int machine_nr)
183 {
184         struct tag *tags = (struct tag *)&default_tags;
185         struct machine_desc *mdesc = NULL, *p;
186         char *from = default_command_line;
187 
188         default_tags.mem.start = PHYS_OFFSET;
189 
190         /*
191          * locate machine in the list of supported machines.
192          */
193         for_each_machine_desc(p)
194                 if (machine_nr == p->nr) {
195                         printk("Machine: %s\n", p->name);
196                         mdesc = p;
197                         break;
198                 }
199 
200         if (!mdesc) {
201                 early_print("\nError: unrecognized/unsupported machine ID"
202                             " (r1 = 0x%08x).\n\n", machine_nr);
203                 dump_machine_table(); /* does not return */
204         }
205 
206         if (__atags_pointer)
207                 tags = phys_to_virt(__atags_pointer);
208         else if (mdesc->atag_offset)
209                 tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
210 
211 #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
212         /*
213          * If we have the old style parameters, convert them to
214          * a tag list.
215          */
216         if (tags->hdr.tag != ATAG_CORE)
217                 convert_to_tag_list(tags);
218 #endif
219         if (tags->hdr.tag != ATAG_CORE) {
220                 early_print("Warning: Neither atags nor dtb found\n");
221                 tags = (struct tag *)&default_tags;
222         }
223 
224         if (mdesc->fixup)
225                 mdesc->fixup(tags, &from, &meminfo);
226 
227         if (tags->hdr.tag == ATAG_CORE) {
228                 if (meminfo.nr_banks != 0)
229                         squash_mem_tags(tags);
230                 save_atags(tags);
231                 parse_tags(tags);
232         }
233 
234         /* parse_early_param needs a boot_command_line */
235         strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
236 
237         return mdesc;
238 }
239 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp