int fdt_path_offset(const void *fdt, const char *path) { const char *end = path + strlen(path); const char *p = path; int offset = 0; CHECK_HEADER(fdt); if (*path != '/') return -FDT_ERR_BADPATH; while (*p) { const char *q; while (*p == '/') p++; if (! *p) return offset; q = strchr(p, '/'); if (! q) q = end; offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); if (offset < 0) return offset; p = q; } return offset; }
int fdt_path_offset(const void *fdt, const char *path) { const char *end = path + strlen(path); const char *p = path; int offset = 0; FDT_CHECK_HEADER(fdt); /* see if we have an alias */ if (*path != '/') { const char *q; int aliasoffset = fdt_path_offset(fdt, "/aliases"); if (aliasoffset < 0) return -FDT_ERR_BADPATH; q = strchr(path, '/'); if (!q) q = end; p = fdt_getprop_namelen(fdt, aliasoffset, path, q - p, NULL); if (!p) return -FDT_ERR_BADPATH; offset = fdt_path_offset(fdt, p); p = q; } while (*p) { const char *q; while (*p == '/') p++; if (! *p) return offset; q = strchr(p, '/'); if (! q) q = end; offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); if (offset < 0) return offset; p = q; } return offset; }
int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) { const char *end = path + namelen; const char *p = path; int offset = 0; FDT_CHECK_HEADER(fdt); /* see if we have an alias */ if (*path != '/') { const char *q = fdt_path_next_separator(path, namelen); if (!q) q = end; p = fdt_get_alias_namelen(fdt, p, q - p); if (!p) return -FDT_ERR_BADPATH; offset = fdt_path_offset(fdt, p); p = q; } while (*p && (p < end)) { const char *q; while (*p == '/') p++; if (*p == '\0' || *p == ':') return offset; q = fdt_path_next_separator(p, end - p); if (!q) q = end; offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); if (offset < 0) return offset; p = q; } return offset; }
int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name) { return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); }
/* * chosen { * bootargs = "console=ttyS0,115200 ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs"; * }; * 호출: int offset = fdt_path_offset(fdt, "/chosen"); */ int fdt_path_offset(const void *fdt, const char *path) { /* * p : "chosen"의 시작 주소 * end : "chosen"의 끝 주소 */ const char *end = path + strlen(path); const char *p = path; int offset = 0; FDT_CHECK_HEADER(fdt); /* see if we have an alias */ if (*path != '/') { // path가 '/'로 시작하지 않으면 path내에서 '/' 위치 찾음 const char *q = strchr(path, '/'); // path내에 '/'가 없으면 끝 주소로 지정 if (!q) q = end; /* * '/'로 시작하지 않았다면 alias라고 가정하고 원래 node명 탐색 * p: alias명 * q-p: alias 길이 */ p = fdt_get_alias_namelen(fdt, p, q - p); // alias도 아닌경우 에러 리턴 if (!p) return -FDT_ERR_BADPATH; offset = fdt_path_offset(fdt, p); p = q; } /* * "chosen"의 alias가 없으면 여기서 탐색 * 여기서는 node의 이름이 "chosen"인지 아닌지 탐색 */ while (*p) { const char *q; // path내에서 '/'가 아닌곳까지 이동 while (*p == '/') p++; // path 끝까지 이동한 경우 if (! *p) return offset; // p를 기준으로 다음 '/' 위치까지 찾아서 q = strchr(p, '/'); // 다음 '/'가 없다면 path의 끝으로 지정 if (! q) q = end; // path에서 '/'로 split 해보면서 // 하위 node들중 해당 이름의 node가 있는지 탐색 offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); if (offset < 0) return offset; p = q; } return offset; }