当前位置: 首页 > news >正文

网站建设的常见问题福建专业网站建设公司

网站建设的常见问题,福建专业网站建设公司,企业互联网营销推广方案,做网站赚广告费好做吗本文主要记录了在友善之臂使用的基于瑞芯微github上uboot的rkdevelop分支#xff0c;以及瑞星微官方的stable-4.4-rk3399-linux分支中#xff0c;uboot如何给linux内核所需要的kernel-dtb的探究过程。 目录 0 - uboot代码准备 1 - 友善之臂版uboot如何获取要加载的设备树 … 本文主要记录了在友善之臂使用的基于瑞芯微github上uboot的rkdevelop分支以及瑞星微官方的stable-4.4-rk3399-linux分支中uboot如何给linux内核所需要的kernel-dtb的探究过程。 目录 0 - uboot代码准备 1 - 友善之臂版uboot如何获取要加载的设备树 1.1 - get_fdt_name 获取设备树dtb文件名 1.2 - get_content() 获取所需dtb的地址 2 - 瑞芯微github上stable-4.4版uboot如何获取设备树 2.1 - uboot-dtb 2.2 - kernel-dtb 2.2.1 - get_file_info() 直接在 resource.img 中查找 rk-kernel.dtb 2.2.2 - EARLY_DISTRO中寻找指定dtb 2.2.3 - HWID判断使用dtb 需要知道的一点是在arm64架构下linux已经弃用mach_xx等文件夹来描述板级信息供linux内核启动时去匹配根节点下的compatible属性来找到对应设备树。 取而代之是单纯的接收bootloader传递过来的单一设备树文件dtb所在的内存地址。所以当多个dtb文件存在镜像中或者内存中时如何找到需要的dtb的这个任务就落在了bootloader肩上。 0 - uboot代码准备 本文中主要涉及到了两个版本的uboot 友善之臂基于瑞芯微 rkdevelop 分支进行修改过的uboot瑞芯微官方github上stable-4.4-rk3399-linux 分支的uboot 分别可以通过以下方式获取。 https://gitlab.com/friendlyelec/rk3399-android-8.1/-/tree/master/u-boothttps://github.com/rockchip-linux/u-boot/tree/stable-4.4-rk3399-linux 1 - 友善之臂版uboot如何获取要加载的设备树 友善之臂用的版本是2014.10版的uboot 首先引用源自 common/cmd_bootrk.c rk_load_image_from_storage() /* loader fdt from resource if content.load_addr NULL */ #ifdef CONFIG_OF_LIBFDTif (!content.load_addr) {#ifdef CONFIG_OF_FROM_RESOURCEputs(load fdt from resouce.\n);content rkimage_load_fdt(get_disk_partition(RESOURCE_NAME));#endif}跟踪看到board/rockchip/common/rkloader/rkimage.c rkimage_load_fdt() resource_content rkimage_load_fdt(const disk_partition_t* ptn) {resource_content content;snprintf(content.path, sizeof(content.path), %s, get_fdt_name());content.load_addr 0;#ifndef CONFIG_RESOURCE_PARTITIONreturn content; #elseif (!ptn)return content;if (!strcmp((char*)ptn-name, BOOT_NAME)|| !strcmp((char*)ptn-name, RECOVERY_NAME)) {//load from bootimgs second data area.unsigned long blksz ptn-blksz;int offset 0;rk_boot_img_hdr *hdr NULL; #ifdef CONFIG_RK_NVME_BOOT_ENhdr memalign(SZ_4K, blksz 2); #elsehdr memalign(ARCH_DMA_MINALIGN, blksz 2); #endifif (StorageReadLba(ptn-start, (void *) hdr, 1 2) ! 0) {return content;}if (!memcmp(hdr-magic, BOOT_MAGIC,BOOT_MAGIC_SIZE) hdr-second_size) {//compute second data areas offset.offset ptn-start (hdr-page_size / blksz);offset ALIGN(hdr-kernel_size, hdr-page_size) / blksz;offset ALIGN(hdr-ramdisk_size, hdr-page_size) / blksz;if (get_content(offset, content))load_content(content);}return content;}//load from spec partition.if (get_content(ptn-start, content))load_content(content);return content; #endif }对于上面两个红框处我们分别讨论 1.1 - get_fdt_name 获取设备树dtb文件名 其代码本质是调用 getenv 从环境变量中取得 dtb_name变量上的字符串 static const char* get_fdt_name(void) {char *name getenv(dtb_name);if (name)return name;if (!gBootInfo.fdt_name[0]) {return FDT_PATH;}return gBootInfo.fdt_name; }而这个“dtb_name“变量中包含的字符串就是我们需要的dtb文件名。它是在 board/rockchip/rk33xx/rk33xx.c rk33xx.c文件中被写入的 /** Board revision list: GPIO4_D1 | GPIO4_D0* 0b00 - NanoPC-T4* 0b01 - NanoPi M4** Extended by ADC_IN4* Group A:* 0x04 - NanoPi NEO4* 0x06 - SOC-RK3399** Group B:* 0x21 - NanoPi M4 Ver2.0*/ static int pcb_rev -1;static void bd_hwrev_init(void) {gpio_direction_input(GPIO_BANK4 | GPIO_D0);gpio_direction_input(GPIO_BANK4 | GPIO_D1);pcb_rev gpio_get_value(GPIO_BANK4 | GPIO_D0);pcb_rev | (gpio_get_value(GPIO_BANK4 | GPIO_D1) 1);if (pcb_rev 0x3) {/* Revision group A: 0x04 ~ 0x13 */pcb_rev 0x4 get_adc_index(4);} else if (pcb_rev 0x1) {int idx get_adc_index(4);/* Revision group B: 0x21 ~ 0x2f */if (idx 0) {pcb_rev 0x20 idx;}} }/* To override __weak symbols */ u32 get_board_rev(void) {return pcb_rev; }static void set_dtb_name(void) {char info[64] {0, };snprintf(info, ARRAY_SIZE(info),rk3399-nanopi4-rev%02x.dtb, get_board_rev());setenv(dtb_name, info); }我们因此知道了友善之臂的nanopi系列板子是通过板上 GPIO4_D1、GPIO4_D0 的输入电平以及 ADC_IN4 脚的输入电压来判断载入什么dtb的 1.2 - get_content() 获取所需dtb的地址 rkimage_load_fdt() 函数中将 “dev_name” 中的设备树名写入到content.path变量中。在 common/resource.c get_content() 函数中 bool get_content(int base_offset, resource_content* content) {bool ret false;index_tbl_entry entry;debug(get_content: base_offset 0x%x\n, base_offset);if (!base_offset) {base_offset get_base_offset();}if (!base_offset) {FBTERR(base offset is NULL!\n);goto end;}if (!get_entry(base_offset, content-path, entry))goto end;content-content_offset entry.content_offset base_offset;content-content_size entry.content_size;ret true; end:return ret; } 将 content.path 传入 get_entry() 函数其函数修改传入的 entry 参数变量。get_entry() 函数也在common/resource.c static bool get_entry(int base_offset, const char* file_path,index_tbl_entry* entry) {。。。ret get_entry_ram(header, table, header.tbl_entry_num* header.tbl_entry_size * BLOCK_SIZE,file_path, entry);end:if (table) {free(table);}return ret; }可知其调用 get_entry_ram 函数将指定dtb文件地址解析并传送到 entry 中。在 common/resource.c get_entry_ram()函数中 。。。 for (i 0; i header.tbl_entry_num; i) {//TODO: support tbl_entry_sizememcpy(entry, table i * header.tbl_entry_size * BLOCK_SIZE,sizeof(*entry));if (memcmp(entry-tag, INDEX_TBL_ENTR_TAG,sizeof(entry-tag))) {FBTERR(Something wrong with index entry:%d!\n, i);goto end;}FBTDBG(Lookup entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n,i, entry-path, entry-content_offset,entry-content_size);if (!strncmp(entry-path, file_path, sizeof(entry-path)))break;} 。。。 从resource镜像的头部中寻找对应的设备树名一条一条比对当比对当前在entry-path中的设备树名与需要的设备树名比对相同时退出。 resource.img 镜像大概长这样 2 - 瑞芯微github上stable-4.4版uboot如何获取设备树 stable-4.4版本的uboot2017.09使用类似现在linux的架构目录。uboot类似kernel也有了自己的设备树方便自身加载初始化。因此这里分两个部分讨论一个是uboot自己的设备树 uboot-dtb 一个是linux需要的设备树 kernel-dtb。 2.1 - uboot-dtb 在 uboot/configs 目录下存放各种defconfig其中包含有一项配置例如firefly的firefly-rk3399 直接指定了使用什么默认设备树 在 uboot\arch\arm\dts\rk3399-firefly.dts 中我们可以看到 /** Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.** SPDX-License-Identifier: GPL-2.0*//dts-v1/; #include dt-bindings/pwm/pwm.h #include dt-bindings/pinctrl/rockchip.h #include rk3399.dtsi #include rk3399-sdram-ddr3-1600.dtsi #include rk3399-u-boot.dtsi/ {model Firefly-RK3399 Board;compatible firefly,firefly-rk3399, rockchip,rk3399;依据这个来进行uboot中设备树的匹配但是注意这个是uboot自用的设备树并不是要传递给kernel的 2.2 - kernel-dtb 在 arch\arm\mach-rockchip\resource_img.c rockchip_read_dtb_file()函数中我们可以看到 。。。 int rockchip_read_dtb_file(void *fdt_addr) {struct resource_file *file;char *def_dtb DTB_FILE;int ret;/* search order: rk-kernel.dtb - distro - hwid */file get_file_info(NULL, def_dtb);if (!file) { #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTBret rockchip_read_distro_dtb(fdt_addr);if (ret 0)return ret; /* found load done */ #endif #ifdef CONFIG_ROCKCHIP_HWID_DTBfile rockchip_read_hwid_dtb(); #endifif (!file)return -ENODEV;} 。。。 从resource.img中获取kernel-dtb有三个阶段图中的红、绿、蓝三框。 2.2.1 - get_file_info() 直接在 resource.img 中查找 rk-kernel.dtb 首先是去resource.img中寻找有没有叫“rk-kernel.dtb”的这个设备树文件宏定义DTB_FILE在 arch\arm\mach-rockchip\resource_img.c 中 static struct resource_file *get_file_info(struct resource_img_hdr *hdr,const char *name) {struct resource_file *file;struct list_head *node;if (list_empty(entrys_head)) {if (init_resource_list(hdr))return NULL;}list_for_each(node, entrys_head) {file list_entry(node, struct resource_file, link);if (!strcmp(file-name, name))return file;}return NULL; } 2.2.2 - EARLY_DISTRO中寻找指定dtb 如果 2.2.1 搜索失败了没有rk-kernel.dtb且定义了 CONFIG_ROCKCHIP_EARLY_DISTRO_DTB 则调用  rockchip_read_distro_dtb(fdt_addr)函数去寻找在arch\arm\mach-rockchip\resource_img.c 中 #ifdef CONFIG_ROCKCHIP_EARLY_DISTRO_DTB static int rockchip_read_distro_dtb(void *fdt_addr) {const char *cmd part list ${devtype} ${devnum} -bootable devplist;char *devnum, *devtype, *devplist;char devnum_part[12];char fdt_hex_str[19];char *fs_argv[5];int size;int ret;if (!rockchip_get_bootdev() || !fdt_addr)return -ENODEV;ret run_command_list(cmd, -1, 0);if (ret)return ret; 。。。 在 arch\arm\mach-rockchip\Kconfig中我们可以看到如果定义了 ROCKCHIP_EARLY_DISTRO_DTB则我们还可以自己定义在镜像文件中dtb的名称 2.2.3 - HWID判断使用dtb 如果2.2.1失败了没有rk-kernel.dtb且定义了CONFIG_ROCKCHIP_HWID_DTB 则调用rockchip_read_hwid_dtb()函数读取硬件引脚来判断使用什么dtb在arch\arm\mach-rockchip\resource_img.c 中 /* Get according to hardware id(GPIO/ADC) */ static struct resource_file *rockchip_read_hwid_dtb(void) {struct resource_file *file;struct list_head *node;/* Find dtb file according to hardware id(GPIO/ADC) */list_for_each(node, entrys_head) {file list_entry(node, struct resource_file, link);if (!strstr(file-name, .dtb))continue;if (strstr(file-name, KEY_WORDS_ADC_CTRL) strstr(file-name, KEY_WORDS_ADC_CH) !rockchip_read_dtb_by_adc(file-name)) {return file;} else if (strstr(file-name, KEY_WORDS_GPIO) !rockchip_read_dtb_by_gpio(file-name)) {return file;}}return NULL; }
http://www.tj-hxxt.cn/news/232653.html

相关文章:

  • 北京网站建设 shwl北京商场招商
  • 网站建设技术团队有多重要性招远专业做网站公司
  • 企业vi设计价格整站seo公司
  • 用html5做课程教学网站wordpress鼠标轨迹
  • 网站的详细设计室内设计和平面设计区别
  • 连云港建网站河北建设工程信息网已取消
  • 电子商城网站模板中国贸易网怎么样
  • 南海网站建设报价网络系统管理属于哪类专业
  • 外贸网站优化免费渠道备案的域名拿来做别的网站
  • 山东高端网站建设附近计算机培训班咨询
  • 商城系统网站模板免费做字体的网站
  • 影院网站怎么做英文字母设计logo生成器
  • o2o商城上的二级网站毕业设计做网站哪种好
  • 网站百度搜索情况和反链接优化建议怎么做网站代销
  • jsp做网站实例教程品牌网站制作公司哪家好
  • 商务网站价格办公室设计图平面布置图
  • 问答推广秦皇岛优化网站排名
  • 搬瓦工做网站网站的结构与布局优化设计
  • 门户网站建设 请示网站添加什么东西才能和用户体验
  • 怎么看网站有没有备案苏州专业网站建设定制
  • 哪里有卖自己做的网站网站语言
  • 衡阳百度网站建设纸业建站服务
  • 龙泉市建设局网站深圳条幅制作
  • 云南建设注册考试中心网站厦门网站开发网络公司
  • 衡水企业网站建设公司wordpress运行
  • pc 手机网站 微站营销型网站建设是什么意思
  • 重庆网站制作服务阳江市网络问政
  • 利用第三方做网站永久发布地址跨境购网站建设
  • 珠海做网站wordpress教育类主题
  • 移动网站建设书籍推荐电子商务平台经营者所具备的功能