前言
设备树chosen节点信息获取的demo
提示:以下是本篇文章正文内容,下面案例可供参考
一、设备树
/* chosen */
chosen: chosen {
bootargs = "console=tty0 console=ttyS0,921600n1 vmalloc=400M \
slub_debug=OFZPU page_owner=on \
swiotlb=noforce androidboot.hardware=mt6765 \
maxcpus=8 loop.max_part=7 \
firmware_class.path=/vendor/firmware";
};
二、demo
这里展示获取boot mode信息的demo
int get_chosen_info()
{
struct device_node *boot_node = NULL;
struct tag_bootmode *tag = NULL;
//这里从设备树获取chosen节点
boot_node = of_find_node_by_path("/chosen");
if (!boot_node)
printk("%s: failed to get boot mode phandle\n", __func__);
else {
//这里通过of_get_property获取chosen节点中的boot信息
tag = (struct tag_bootmode *)of_get_property(boot_node,
"atag,boot", NULL);
if (!tag)
printk("%s: failed to get atag,boot\n", __func__);
else {
printk("%s: size:0x%x tag:0x%x bootmode:0x%x boottype:0x%x\n",
__func__, tag->size, tag->tag,
tag->bootmode, tag->boottype);
}
}
return tag->bootmode;
}
这里展示一下mtk是如何在lk通过chosen传递信息到kernel
static int __parse_tag_videolfb_extra(struct device_node *node)
{
void *prop;
unsigned long size = 0;
u32 fb_base_h, fb_base_l;
prop = (void *)of_get_property(node,
"atag,videolfb-fb_base_h", NULL);
if (!prop)
return -1;
fb_base_h = of_read_number(prop, 1);
prop = (void *)of_get_property(node,
"atag,videolfb-fb_base_l", NULL);
if (!prop)
return -1;
fb_base_l = of_read_number(prop, 1);
fb_base = ((u64) fb_base_h << 32) | (u64) fb_base_l;
prop = (void *)of_get_property(node,
"atag,videolfb-islcmfound", NULL);
if (!prop)
return -1;
islcmconnected = of_read_number(prop, 1);
prop = (void *)of_get_property(node,
"atag,videolfb-islcm_inited", NULL);
if (!prop)
is_lcm_inited = 1;
else
is_lcm_inited = of_read_number(prop, 1);
prop = (void *)of_get_property(node,
"atag,videolfb-fps", NULL);
if (!prop)
return -1;
lcd_fps = of_read_number(prop, 1);
if (lcd_fps == 0)
lcd_fps = 6000;
prop = (void *)of_get_property(node,
"atag,videolfb-vramSize", NULL);
if (!prop)
return -1;
vramsize = of_read_number(prop, 1);
prop = (void *)of_get_property(node,
"atag,videolfb-fb_base_l", NULL);
if (!prop)
return -1;
fb_base_l = of_read_number(prop, 1);
prop = (void *)of_get_property(node,
"atag,videolfb-lcmname", (int *)&size);
if (!prop)
return -1;
if (size >= sizeof(mtkfb_lcm_name)) {
DISPCHECK("%s: error to get lcmname size=%ld\n",
__func__, size);
return -1;
}
memset((void *)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
strncpy((char *)mtkfb_lcm_name, prop, sizeof(mtkfb_lcm_name));
mtkfb_lcm_name[size] = '\0';
DISPMSG("__parse_tag_videolfb_extra done\n");
return 0;
}
三、在lk如何写入信息到chosen
感兴趣的话,可以查看lk中上述videolfb-lcmname等信息的在lk中如何写入到kernel。
这里贴一段相关的代码
//fdt是设备树的handle,offset就是chosen在设备树中位置
offset = fdt_path_offset(fdt, "/chosen");
//这个func主要是做buf内容的添加
ptr = (char *)target_atag_videolfb((unsigned *)buf, FDT_BUFF_SIZE);
//主要是通过fdt_setprop去写入
ret = fdt_setprop(fdt, offset, "atag,videolfb", buf, ptr - buf);
if (ret) {
assert(0);
return FALSE;
}
#include <platform/mt_disp_drv.h>
#include <platform/disp_drv.h>
unsigned *target_atag_videolfb(unsigned *ptr, size_t buf_size)
{
extern unsigned long long fb_addr_pa_k;
const char *lcmname = mt_disp_get_lcm_id();
unsigned int *p = NULL;
unsigned long long *phy_p = (unsigned long long *)ptr;
*phy_p = fb_addr_pa_k;
p = (unsigned int*)(phy_p + 1);
UINT32 fps = mt_disp_get_lcd_time();
*p++ = DISP_IsLcmFound();
*p++ = fps;
*p++ = DISP_GetVRamSize();
strncpy((char *)p, lcmname, (buf_size - 5 * sizeof(unsigned)));
p += (strlen(lcmname) + 1 + 4) >> 2;
dprintf(CRITICAL, "videolfb - fb_base = 0x%llx\n",fb_addr_pa_k);
dprintf(CRITICAL, "videolfb - islcmfound = %d\n",DISP_IsLcmFound());
dprintf(CRITICAL, "videolfb - fps = %d\n", fps);
dprintf(CRITICAL, "videolfb - vram = %d\n",DISP_GetVRamSize());
dprintf(CRITICAL, "videolfb - lcmname = %s\n",lcmname);
return (unsigned *)p;
}