atags_to_fdt.c



在arm32 的时候kernel 一般都是自解的,uboot一般讲uImage copy到dram的每一位置,然后指针跳过去就可以执行了。在没有device tree的时候,uboot 和 kernel 之前是通过atags来传递数据的。后面会详细写这部分。但是kernel这边再enable device tree之后,如果uboot 没有enable device tree,即uboot还是按照atags的防暑传递给kernel,kernel 能正确接受到这个消息吗?
当然是肯定的,在自解压kernel的时候,kernel 会做一个atags_to_fdt的动作.但是这个函数比较简单只将ATAG_CMDLINE/ATAG_MEM/ATAG_INITRD2.其他的如cpu等,这些都没有做。
arch/arm/boot/compressed/atags_to_fdt.c


108 int atags_to_fdt(void *atag_list, void *fdt, int total_space)
109 {
110         struct tag *atag = atag_list;
111         /* In the case of 64 bits memory size, need to reserve 2 cells for
112          * address and size for each bank */
113         uint32_t mem_reg_property[2 * 2 * NR_BANKS];
114         int memcount = 0;
115         int ret, memsize;
116 
117         /* make sure we've got an aligned pointer */
118         if ((u32)atag_list & 0x3)
119                 return 1;
120 
121         /* if we get a DTB here we're done already */
122         if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC))
123                return 0;
124 
125         /* validate the ATAG */
126         if (atag->hdr.tag != ATAG_CORE ||
127             (atag->hdr.size != tag_size(tag_core) &&
128              atag->hdr.size != 2))
129                 return 1;
130 
131         /* let's give it all the room it could need */
132         ret = fdt_open_into(fdt, fdt, total_space);
133         if (ret < 0)
134                 return ret;
135 
136         for_each_tag(atag, atag_list) {
137                 if (atag->hdr.tag == ATAG_CMDLINE) {
138                         /* Append the ATAGS command line to the device tree
139                          * command line.
140                          * NB: This means that if the same parameter is set in
141                          * the device tree and in the tags, the one from the
142                          * tags will be chosen.
143                          */
144                         if (do_extend_cmdline)
145                                 merge_fdt_bootargs(fdt,
146                                                    atag->u.cmdline.cmdline);
147                         else
148                                 setprop_string(fdt, "/chosen", "bootargs",
149                                                atag->u.cmdline.cmdline);
150                 } else if (atag->hdr.tag == ATAG_MEM) {
151                         if (memcount >= sizeof(mem_reg_property)/4)
152                                 continue;
153                         if (!atag->u.mem.size)
154                                 continue;
155                         memsize = get_cell_size(fdt);
156 
157                         if (memsize == 2) {
158                                 /* if memsize is 2, that means that
159                                  * each data needs 2 cells of 32 bits,
160                                  * so the data are 64 bits */
161                                 uint64_t *mem_reg_prop64 =
162                                         (uint64_t *)mem_reg_property;
163                                 mem_reg_prop64[memcount++] =
164                                         cpu_to_fdt64(atag->u.mem.start);
165                                 mem_reg_prop64[memcount++] =
166                                         cpu_to_fdt64(atag->u.mem.size);
167                         } else {
168                                 mem_reg_property[memcount++] =
169                                         cpu_to_fdt32(atag->u.mem.start);
170                                 mem_reg_property[memcount++] =
171                                         cpu_to_fdt32(atag->u.mem.size);
172                         }
173 
174                 } else if (atag->hdr.tag == ATAG_INITRD2) {
175                         uint32_t initrd_start, initrd_size;
176                         initrd_start = atag->u.initrd.start;
177                         initrd_size = atag->u.initrd.size;
178                         setprop_cell(fdt, "/chosen", "linux,initrd-start",
179                                         initrd_start);
180                         setprop_cell(fdt, "/chosen", "linux,initrd-end",
181                                         initrd_start + initrd_size);
182                 }
183         }
184 
185         if (memcount) {
186                 setprop(fdt, "/memory", "reg", mem_reg_property,
187                         4 * memcount * memsize);
188         }
189 
190         return fdt_pack(fdt);
191 }
192 

你可能感兴趣的:(Linux,源码分析)