📄 mk_flatdevtree.c
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright IBM Corporation 2007 * * Authors: Ryan Harper <ryanh@us.ibm.com> */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <dirent.h>#include <unistd.h>#include <libgen.h> #include <inttypes.h>#include <math.h>#include <errno.h>#include <sys/types.h>#include <sys/dir.h>#include <sys/stat.h>#include <sys/param.h>#include <xc_private.h> /* for PERROR() */#include <xc_dom.h>#include "mk_flatdevtree.h"static uint32_t current_phandle = 0;static uint32_t get_phandle(void){ return current_phandle++;}static int readfile(const char *fullpath, void *data, int len){ struct stat st; int saved_errno; int rc = -1; int fd; if ((fd = open(fullpath, O_RDONLY)) == -1) { PERROR("%s: failed to open file %s", __func__, fullpath); return -1; } if ((rc = fstat(fd, &st)) == -1) { PERROR("%s: failed to stat fd %d", __func__, fd); goto error; } if (S_ISREG(st.st_mode)) rc = read(fd, data, len); close(fd); return rc;error: saved_errno = errno; close(fd); errno = saved_errno; return -1;}/* * @property - string to check against the filter list * @filter - NULL terminated list of strings * * compare @property string to each string in @filter * * return 1 if @property matches any filter, otherwise 0 * */static int match(const char *property, const char **filter){ int i; for (i=0; filter[i] != NULL; i++) { /* compare the filter to property */ if (strncmp(property, filter[i], strlen(filter[i])) == 0) return 1; } return 0;}/* * copy the node at @dirpath filtering out any properties that match in @propfilter */static int copynode(struct ft_cxt *cxt, const char *dirpath, const char **propfilter){ struct dirent *tree; struct stat st; DIR *dir; char fullpath[MAX_PATH]; char *bname = NULL; char *basec = NULL; int saved_errno; if ((dir = opendir(dirpath)) == NULL) { PERROR("%s: failed to open dir %s", __func__, dirpath); return -1; } while (1) { if ((tree = readdir(dir)) == NULL) break; /* reached end of directory entries */ /* ignore . and .. */ if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) continue; /* build full path name of the file, for stat() */ if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath, tree->d_name) >= sizeof(fullpath)) { PERROR("%s: failed to build full path", __func__); goto error; } /* stat the entry */ if (stat(fullpath, &st) < 0) { PERROR("%s: failed to stat file %s", __func__, fullpath); goto error; } if (S_ISDIR(st.st_mode)) { /* start a new node for a dir */ ft_begin_node(cxt, tree->d_name); /* copy everything in this dir */ if (copynode(cxt, fullpath, propfilter) < 0) { PERROR("%s: failed to copy node @ %s", __func__, fullpath); goto error; } /* end the node */ ft_end_node(cxt); } /* add files in dir as properties */ else if (S_ISREG(st.st_mode)) { if ((basec = strdup(fullpath)) == NULL) { PERROR("%s: failed to dupe string", __func__); goto error; } if ((bname = basename(basec)) == NULL) { PERROR("%s: basename() failed", __func__); goto error; } /* only add files that don't match the property filter string */ if (!match(bname, propfilter)) { char data[BUFSIZE]; int len; /* snarf the data and push into the property */ if ((len = readfile(fullpath, data, sizeof(data))) < 0) { PERROR("%s: failed to read data from file %s", __func__, fullpath); goto error; } ft_prop(cxt, tree->d_name, data, len); } /* strdup mallocs memory */ if (basec != NULL ) { free(basec); basec = NULL; } } } closedir(dir); return 0;error: saved_errno = errno; /* strdup mallocs memory */ if (basec != NULL ) { free(basec); basec = NULL; } closedir(dir); errno = saved_errno; return -1;}static int find_cpu0(char *cpupath, int len){ const char path[] = "/proc/device-tree/cpus"; const char device[] = "device_type"; const char dev_cpu[] = "cpu"; const char reg[] = "reg"; char data[sizeof(dev_cpu)]; char prop[MAX_PATH]; char node[MAX_PATH]; struct dirent *tree; struct stat st; DIR* dir; int saved_errno; int found = 0; if ((dir = opendir(path)) == NULL) { PERROR("%s: failed to open directory %s", __func__, path); return -1; } while (!found) { if ((tree = readdir(dir)) == NULL) break; /* reached end of directory entries */ /* ignore ., .. */ if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) continue; /* build full path name of the file, for stat() */ if (snprintf(node, sizeof(node), "%s/%s", path, tree->d_name) >= sizeof(node)) { PERROR("%s: failed to concat strings", __func__); goto error; } /* stat the entry */ if (stat(node, &st) < 0) { PERROR("%s: failed to stat file %s", __func__, node); /* something funny happen in /proc/device-tree, but march onward */ continue; } /* for each dir, check the device_type property until we find 'cpu'*/ if (S_ISDIR(st.st_mode)) { /* construct path to device_type */ if (snprintf(prop, sizeof(prop), "%s/%s", node, device) >= sizeof(prop)) { PERROR("%s: failed to concat strings", __func__); goto error; } /* read device_type into buffer */ if ((readfile(prop, data, sizeof(data))) < 0) { PERROR("%s: failed to read data from file %s", __func__, prop); goto error; } /* if the device_type is 'cpu', and reg is 0 * return the path where we found it */ if (strcmp(data, "cpu") == 0) { /* construct path to reg */ if (snprintf(prop, sizeof(prop), "%s/%s", node, reg) >= sizeof(prop)) { PERROR("%s: failed to concat strings", __func__); goto error; } /* using data buffer since reg and device_type values have same size */ if ((readfile(prop, data, sizeof(data))) < 0) { PERROR("%s: failed to read data from file %s", __func__, prop); goto error; } /* now check property "reg" for value 0 */ if ((u32)*data == 0) { if (snprintf(cpupath, len, "%s", node) >= len) { PERROR("%s: failed to copy cpupath", __func__); goto error; } found = 1; } } } } closedir(dir); return found;error: saved_errno = errno; closedir(dir); errno = saved_errno; return -1;}void free_devtree(struct ft_cxt *root){ if ((root != NULL) && root->bph != NULL) { free(root->bph); root->bph = NULL; }}int make_devtree(struct ft_cxt *root, struct xc_dom_image *dom, unsigned long shadow_mb){ struct boot_param_header *bph = NULL; uint64_t val[2]; uint32_t val32[2]; uint64_t shared_info_paddr = dom->shared_info_pfn << PAGE_SHIFT; uint64_t xenstore_paddr = dom->xenstore_pfn << PAGE_SHIFT; uint64_t console_paddr = dom->console_pfn << PAGE_SHIFT; long remaining; unsigned long ramdisk_start; unsigned long ramdisk_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -