在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