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

企业营销型网站设计免费建站哪个最好

企业营销型网站设计,免费建站哪个最好,国家卫生资格考试官网,wordpress识图搜索代码本文主要记录了在友善之臂使用的基于瑞芯微github上uboot的rkdevelop分支,以及瑞星微官方的stable-4.4-rk3399-linux分支中,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-boot
  • https://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 bootimg's 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 area's 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版本的uboot(2017.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.qdjiajiao.com/news/5985.html

相关文章:

  • 做电商网站费用软文通
  • 芜湖做公司网站手机网站智能建站
  • 做网站需要每年交钱吗seo公司厦门
  • 石柱网站建设网络营销文案策划都有哪些
  • 做网站要求的分辨率是什么意思百度网址大全电脑版
  • 设计网站会员哪个好用搜索营销
  • 网站建设小公司生存百度推广网站
  • 网站vr视角怎么做网站推广网络营销方案
  • 嘉兴市城乡规划建设管理网站seo和竞价排名的区别
  • 承德做网站西安百度公司开户
  • 化妆品网站建设实施背景软文大全800字
  • 秦皇岛市房价成都优化网站哪家公司好
  • 自制app软件的软件seo黑帽培训
  • 东莞网站建设做网站网站点击量与排名
  • 重庆九龙坡营销型网站建设公司推荐东莞网站seo优化
  • 百度指数关键词搜索趋势seo交流中心
  • 东莞招投标服务中心seo优化宣传
  • icp网站备案系统seo收费低
  • wordpress快速登录插件网站seo外链建设
  • 手机网站 微信网站seo算法是什么
  • 网站公司动态做不了怎么办东莞最新消息今天
  • 国外做储物柜的网站网站模板怎么建站
  • 在建设局网站上怎么样总监解锁网站注册时间查询
  • 产品宣传网站开发百度推广方案
  • 如何在word里做网站中国网站建设公司
  • 广州网站建设报价单怎么优化网站排名
  • 搜索网站的方法seo基础入门免费教程
  • 蚌埠网站制作吉林网站seo
  • 松江做网站的公司长沙seo网站
  • 网页个人简历设计怎么做北京seo人员