📄 mk_flatdevtree.c
字号:
unsigned long rma_bytes = 1 << dom->realmodearea_log; int64_t shadow_mb_log; uint64_t pft_size; char cpupath[MAX_PATH]; const char *propfilter[] = { "ibm", "linux,", NULL }; char *cpupath_copy = NULL; char *cpuname = NULL; int saved_errno; int dtb_fd = -1; uint32_t cpu0_phandle = get_phandle(); uint32_t xen_phandle = get_phandle(); uint32_t rma_phandle = get_phandle(); /* initialize bph to prevent double free on error path */ root->bph = NULL; /* carve out space for bph */ if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) { PERROR("%s: Failed to malloc bph buffer size", __func__); goto error; } /* NB: struct ft_cxt root defined at top of file */ /* root = Tree() */ ft_begin(root, bph, BPH_SIZE); /* you MUST set reservations BEFORE _starting_the_tree_ */ /* reserve shared_info_t page */ if (shared_info_paddr) { val[0] = cpu_to_be64((u64) shared_info_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_add_rsvmap(root, val[0], val[1]); } /* reserve console page for domU */ if (console_paddr) { val[0] = cpu_to_be64((u64) console_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_add_rsvmap(root, val[0], val[1]); } /* reserve xen store page for domU */ if (xenstore_paddr) { val[0] = cpu_to_be64((u64) xenstore_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_add_rsvmap(root, val[0], val[1]); } /* reserve space for initrd if needed */ ramdisk_start = dom->ramdisk_seg.pfn << PAGE_SHIFT; ramdisk_size = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; if (ramdisk_size > 0) { val[0] = cpu_to_be64((u64) ramdisk_start); val[1] = cpu_to_be64((u64) ramdisk_size); ft_add_rsvmap(root, val[0], val[1]); } /* NB: ft_add_rsvmap() already terminates with a NULL reservation for us */ /* done with reservations, _starting_the_tree_ */ ft_begin_tree(root); /* make root node */ ft_begin_node(root, ""); /* root.addprop('device_type', 'chrp-but-not-really\0') */ ft_prop_str(root, "device_type", "chrp-but-not-really"); /* root.addprop('#size-cells', 2) */ ft_prop_int(root, "#size-cells", 2); /* root.addprop('#address-cells', 2) */ ft_prop_int(root, "#address-cells", 2); /* root.addprop('model', 'Momentum,Maple-D\0') */ ft_prop_str(root, "model", "Momentum,Maple-D"); /* root.addprop('compatible', 'Momentum,Maple\0') */ ft_prop_str(root, "compatible", "Momentum,Maple"); /* start chosen node */ ft_begin_node(root, "chosen"); /* chosen.addprop('cpu', cpu0.get_phandle()) */ ft_prop_int(root, "cpu", cpu0_phandle); /* chosen.addprop('rma', rma.get_phandle()) */ ft_prop_int(root, "memory", rma_phandle); /* chosen.addprop('linux,stdout-path', '/xen/console\0') */ ft_prop_str(root, "linux,stdout-path", "/xen/console"); /* chosen.addprop('interrupt-controller, xen.get_phandle()) */ ft_prop_int(root, "interrupt-controller", xen_phandle); /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */ if (dom->cmdline != NULL) ft_prop_str(root, "bootargs", dom->cmdline); /* mark where the initrd is, if present */ if (ramdisk_size > 0) { val[0] = cpu_to_be64((u64) ramdisk_start); val[1] = cpu_to_be64((u64) ramdisk_start + ramdisk_size); ft_prop(root, "linux,initrd-start", &(val[0]), sizeof(val[0])); ft_prop(root, "linux,initrd-end", &(val[1]), sizeof(val[1])); } /* end chosen node */ ft_end_node(root); /* xen = root.addnode('xen') */ ft_begin_node(root, "xen"); /* xen.addprop('version', 'Xen-3.0-unstable\0') */ ft_prop_str(root, "compatible", "Xen-3.0-unstable"); /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */ val[0] = cpu_to_be64((u64) dom->guest_domid); val[1] = cpu_to_be64((u64) 0); ft_prop(root, "reg", val, sizeof(val)); /* point to shared_info_t page base addr */ val[0] = cpu_to_be64((u64) shared_info_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_prop(root, "shared-info", val, sizeof(val)); /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */ /* libxc doesn't know the domain name, that is purely a xend thing */ /* ft_prop_str(root, "domain-name", domain_name); */ /* add xen/linux,phandle for chosen/interrupt-controller */ ft_prop_int(root, "linux,phandle", xen_phandle); if (console_paddr != 0) { /* xencons = xen.addnode('console') */ ft_begin_node(root, "console"); /* console_paddr */ val[0] = cpu_to_be64((u64) console_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_prop(root, "reg", val, sizeof(val)); /* xencons.addprop('interrupts', console_evtchn, 0) */ val32[0] = cpu_to_be32((u32) dom->console_evtchn); val32[1] = cpu_to_be32((u32) 0); ft_prop(root, "interrupts", val32, sizeof(val32)); /* end of console */ ft_end_node(root); } if (xenstore_paddr != 0) { /* start store node */ ft_begin_node(root, "store"); /* store paddr */ val[0] = cpu_to_be64((u64) xenstore_paddr); val[1] = cpu_to_be64((u64) PAGE_SIZE); ft_prop(root, "reg", val, sizeof(val)); /* store event channel */ val32[0] = cpu_to_be32((u32) dom->xenstore_evtchn); val32[1] = cpu_to_be32((u32) 0); ft_prop(root, "interrupts", val32, sizeof(val32)); /* end of store */ ft_end_node(root); } /* end of xen node */ ft_end_node(root); /* rma = root.addnode('memory@0') */ ft_begin_node(root, "memory@0"); /* rma.addprop('reg', long(0), long(rma_bytes)) */ val[0] = cpu_to_be64((u64) 0); val[1] = cpu_to_be64((u64) rma_bytes); ft_prop(root, "reg", val, sizeof(val)); /* rma.addprop('device_type', 'memory\0') */ ft_prop_str(root, "device_type", "memory"); /* add linux,phandle for chosen/rma node */ ft_prop_int(root, "linux,phandle", rma_phandle); /* end of memory@0 */ ft_end_node(root); /* calculate remaining bytes from total - rma size */ remaining = (dom->total_pages << PAGE_SHIFT) - rma_bytes; /* memory@<rma_bytes> is all remaining memory after RMA */ if (remaining > 0) { char mem[MAX_PATH]; if (snprintf(mem, sizeof(mem), "memory@%lx", rma_bytes) >= sizeof(mem)) { PERROR("%s: failed to build memory string", __func__); goto error; } /* memory@<rma_bytes> is all remaining memory after RMA */ ft_begin_node(root, mem); /* mem.addprop('reg', long(rma_bytes), long(remaining)) */ val[0] = cpu_to_be64((u64) rma_bytes); val[1] = cpu_to_be64((u64) remaining); ft_prop(root, "reg", val, sizeof(val)); /* mem.addprop('device_type', 'memory\0') */ ft_prop_str(root, "device_type", "memory"); /* end memory@<rma_bytes> node */ ft_end_node(root); } /* add CPU nodes */ /* cpus = root.addnode('cpus') */ ft_begin_node(root, "cpus"); /* cpus.addprop('smp-enabled') */ ft_prop(root, "smp-enabled", NULL, 0); /* cpus.addprop('#size-cells', 0) */ ft_prop_int(root, "#size-cells", 0); /* cpus.addprop('#address-cells', 1) */ ft_prop_int(root, "#address-cells", 1); /* * Copy all properties the system firmware gave us from a * CPU node in the device tree. */ if (find_cpu0(cpupath, sizeof(cpupath)) <= 0) { PERROR("%s: failed find cpu0 node in host devtree", __func__); goto error; } /* get the basename from path to cpu device */ if ((cpupath_copy = strdup(cpupath)) == NULL) { PERROR("%s: failed to dupe string", __func__); goto error; } if ((cpuname = basename(cpupath_copy)) == NULL) { PERROR("%s: basename() failed", __func__); goto error; } /* start node for the cpu */ ft_begin_node(root, cpuname); /* strdup() mallocs memory */ if ( cpupath_copy != NULL ) { free(cpupath_copy); cpupath_copy = NULL; } /* copy over most properties from host tree for cpu */ if (copynode(root, cpupath, propfilter) < 0) { PERROR("%s: failed to copy node", __func__); goto error; } /* calculate the pft-size */ shadow_mb_log = (int)log2((double)shadow_mb); pft_size = shadow_mb_log + 20; val32[0] = cpu_to_be32((u32) 0); val32[1] = cpu_to_be32((u32) pft_size); ft_prop(root, "ibm,pft-size", val32, sizeof(val32)); /* make phandle for cpu0 */ ft_prop_int(root, "linux,phandle", cpu0_phandle); /* end <cpuname> node */ ft_end_node(root); /* end cpus node */ ft_end_node(root); /* end root node */ ft_end_node(root); /* end of the tree */ if (ft_end_tree(root) != 0) { PERROR("%s: failed to end tree", __func__); goto error; } /* write a copy of the tree to a file */ if ((dtb_fd = creat(DTB_FILE, S_IRUSR | S_IWUSR)) == -1) { PERROR("%s: failed to open file %s", __func__, DTB_FILE); goto error; } if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) { PERROR("%s: failed to write blob to file", __func__); goto error; } return 0; error: saved_errno = errno; /* strdup() mallocs memory */ if ( cpupath_copy != NULL ) { free(cpupath_copy); cpupath_copy = NULL; } /* free bph buffer */ free_devtree(root); if (dtb_fd) close(dtb_fd); errno = saved_errno; return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -