125,128c125,130
< AtagCore *ac = new AtagCore;
< ac->flags(1); // read-only
< ac->pagesize(8192);
< ac->rootdev(0);
---
> Addr addr = 0;
> // Check if the kernel image has a symbol that tells us it supports
> // device trees.
> bool kernel_has_fdt_support =
> kernelSymtab->findAddress("unflatten_device_tree", addr);
> bool dtb_file_specified = params()->dtb_filename != "";
130,137c132,135
< AddrRangeList atagRanges = physmem.getConfAddrRanges();
< if (atagRanges.size() != 1) {
< fatal("Expected a single ATAG memory entry but got %d\n",
< atagRanges.size());
< }
< AtagMem *am = new AtagMem;
< am->memSize(atagRanges.begin()->size());
< am->memStart(atagRanges.begin()->start);
---
> if (kernel_has_fdt_support && dtb_file_specified) {
> // Kernel supports flattened device tree and dtb file specified.
> // Using Device Tree Blob to describe system configuration.
> inform("Loading DTB file: %s\n", params()->dtb_filename);
139,140c137,155
< AtagCmdline *ad = new AtagCmdline;
< ad->cmdline(params()->boot_osflags);
---
> ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true);
> if (!dtb_file) {
> fatal("couldn't load DTB file: %s\n", params()->dtb_filename);
> }
> dtb_file->setTextBase(params()->atags_addr);
> dtb_file->loadSections(physProxy);
> delete dtb_file;
> } else {
> // Using ATAGS
> // Warn if the kernel supports FDT and we haven't specified one
> if (kernel_has_fdt_support) {
> assert(!dtb_file_specified);
> warn("Kernel supports device tree, but no DTB file specified\n");
> }
> // Warn if the kernel doesn't support FDT and we have specified one
> if (dtb_file_specified) {
> assert(!kernel_has_fdt_support);
> warn("DTB file specified, but no device tree support in kernel\n");
> }
142c157,160
< DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, params()->boot_osflags.c_str());
---
> AtagCore *ac = new AtagCore;
> ac->flags(1); // read-only
> ac->pagesize(8192);
> ac->rootdev(0);
144c162,169
< AtagNone *an = new AtagNone;
---
> AddrRangeList atagRanges = physmem.getConfAddrRanges();
> if (atagRanges.size() != 1) {
> fatal("Expected a single ATAG memory entry but got %d\n",
> atagRanges.size());
> }
> AtagMem *am = new AtagMem;
> am->memSize(atagRanges.begin()->size());
> am->memStart(atagRanges.begin()->start);
146,148c171,172
< uint32_t size = ac->size() + am->size() + ad->size() + an->size();
< uint32_t offset = 0;
< uint8_t *boot_data = new uint8_t[size << 2];
---
> AtagCmdline *ad = new AtagCmdline;
> ad->cmdline(params()->boot_osflags);
150,153c174
< offset += ac->copyOut(boot_data + offset);
< offset += am->copyOut(boot_data + offset);
< offset += ad->copyOut(boot_data + offset);
< offset += an->copyOut(boot_data + offset);
---
> DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, params()->boot_osflags.c_str());
155,156c176
< DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
< DDUMP(Loader, boot_data, size << 2);
---
> AtagNone *an = new AtagNone;
158c178,180
< physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
---
> uint32_t size = ac->size() + am->size() + ad->size() + an->size();
> uint32_t offset = 0;
> uint8_t *boot_data = new uint8_t[size << 2];
159a182,192
> offset += ac->copyOut(boot_data + offset);
> offset += am->copyOut(boot_data + offset);
> offset += ad->copyOut(boot_data + offset);
> offset += an->copyOut(boot_data + offset);
>
> DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
> DDUMP(Loader, boot_data, size << 2);
>
> physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
> }
>