牡丹江省,seo服务器配置,新的数据新闻,网站建设逻辑组织的几种模型1. 和其它内核代码类似。 显示驱动的分析都是由 drivers/video/fbmem.c开始#xff0c;fbmem.c是显示驱动的抽象#xff0c;实际只是一个框架性的东西。 fbmem_init 中实现了一个字符设备驱动#xff0c;并创建了class#xff0c;但是没有生成设备文件。 这个字符设备驱动的…1. 和其它内核代码类似。 显示驱动的分析都是由 drivers/video/fbmem.c开始fbmem.c是显示驱动的抽象实际只是一个框架性的东西。 fbmem_init 中实现了一个字符设备驱动并创建了class但是没有生成设备文件。 这个字符设备驱动的file_operations里面的函数实质上都是从struct fb_info *registered_fb[FB_MAX] 这个 fb_info的结构体数组中去调用 fb_ops 这个结构体中函数指针。数组下标为次设备号。那么这个结构体是如何赋值的 呢 fbmem.c里定义 register_framebuffer这个函数。真正的显示设备都是调用这个函数来给registered_fb这个数组赋值 然后再去创建设备文件。 2. 我们搜索register_framebuffer这个文件有如下几处 drivers/gpu/drm/drm_fb_helper.c drivers/video/s3c-fb.c 3. 我们先来看看s3c-fb.c 这个文件注册了一个平台总线设备驱动程序在其probe函数中调用 register_framebuffer。 那么这个驱动的probe的函数什么时候调用呢 接下来我们看一下内核中实现平台总线驱动代码注意平台总线驱动是内核实现的。 4. drivers/base/platform.c 主要看platform_match这个函数也就是平台总线设备驱动和平台总线设备是如何匹配的知道了匹配规则我们 就知道如何去需找对应的平台设备了。 先看这句话 if (pdrv-id_table) return platform_match_id(pdrv-id_table, pdev) ! NULL; return (strcmp(pdev-name, drv-name) 0); 如何平台总线设备驱动中有id_table的话那么调用platform_match_id这个函数。 我们再看一下platform_match_id函数做个什么。 while (id-name[0]) { if (strcmp(pdev-name, id-name) 0) { pdev-id_entry id; return id; } id; } 很显然就是拿平台总线设备的name去挨个比较平台总线设备驱动的id_table匹配成功测返回id。 如果没有匹配成功则再去比较平台总线设备的名称和平台总线驱动的名称。也就是 return (strcmp(pdev-name, drv-name) 0); 这句。 一旦匹配成功那么内核会自动调用平台总线设备驱动的probe函数。 5. 那么接下来我们就看看s3c-fb.c这个文件里实现的平台总线设备驱动程序的name和id_table static struct platform_driver s3c_fb_driver { .probe s3c_fb_probe, .remove s3c_fb_remove, .id_table s3c_fb_driver_ids, .driver { .name s3c-fb, .owner THIS_MODULE, .pm s3cfb_pm_ops, }, };
static struct platform_device_id s3c_fb_driver_ids[] { { .name s3c-fb, .driver_data (unsigned long)s3c_fb_data_64xx, }, { .name s5pc100-fb, .driver_data (unsigned long)s3c_fb_data_s5pc100, }, { .name s5pv210-fb, .driver_data (unsigned long)s3c_fb_data_s5pv210, }, { .name exynos4-fb, .driver_data (unsigned long)s3c_fb_data_exynos4, }, { .name exynos5-fb, .driver_data (unsigned long)s3c_fb_data_exynos5, }, { .name s3c2443-fb, .driver_data (unsigned long)s3c_fb_data_s3c2443, }, { .name s5p64x0-fb, .driver_data (unsigned long)s3c_fb_data_s5p64x0, }, {}, }; 有了第4点的分析我们可以搜索上面红字部分来查找对应的平台总线设备了。 6. 搜索s3c-fb找到了 arch/arm/plat-samsung/devs.c这个文件 搜索exynos4-fb找到了 arch/arm/mach-exynos/common.c 其它name我们应该不用理会都是其它soc名称。 在devs.c里定义了 struct platform_device s3c_device_fb { .name s3c-fb, .id -1, .num_resources ARRAY_SIZE(s3c_fb_resource), .resource s3c_fb_resource, .dev { .dma_mask samsung_device_dma_mask, .coherent_dma_mask DMA_BIT_MASK(32), }, }; 在common.c里是这句 s5p_fb_setname(0,exynos4-fb); 展开实际是这样s5p_device_fimd0.name name; struct platform_device s5p_device_fimd0 { .name s5p-fb, 这块被改为了 exynos4-fb .id 0, .num_resources ARRAY_SIZE(s5p_fimd0_resource), .resource s5p_fimd0_resource, .dev { .dma_mask samsung_device_dma_mask, .coherent_dma_mask DMA_BIT_MASK(32), }, }; 从以上分析实际定义了两个设备s3c-fb,exynos4-fb。 7. 现在找到了平台总线的设备和驱动后我们要做的主要事情就是去修改lcd的各种参数主要是fb_info结构体 的fb_var_screeninfo结构体这里面记录了lcd的主要9个参数。 行前肩行后肩行同步信号脉宽帧前肩帧后肩帧同步信号脉宽像素时钟频率x轴像素点y轴像素点。 分析了s3c_fb.c文件后发现是这句来赋值fb_videomode_to_var(fbinfo-var, initmode); 经过再次分析后实际数据是来源于平台总线设备中pd pdev-dev.platform_data; 8. 那么我们再次回到devs.c这个文件因为上面两个平台总线设备均定义在次文件中。 但是查看s3c_device_fb和s5p_device_fimd0这两个平台设备结构体后没有发现platform_data。那么一定是后面 专门有赋值的地方。查找后发现 void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) { s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), s3c_device_fb); }
void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd) { s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), s5p_device_fimd0); } 经过搜索发现s5p_fimd0_set_platdata在 下面文件中调用 arch/arm/mach-exynos/mach-nanopc-t1.c arch/arm/mach-exynos/mach-smdk4x12.c 这个文件应该没用 s3c_fb_set_platdata没有被任何地方调用那么s3c_device_fb这个设备应该没有用处我认为应该去掉。 9. 接下来我们主要分析s5p_device_fimd0这个设备。 在mach-nano-t1.c 这句 两句 nanopc_fb_init_pdata(nanopc_fb_pdata); s5p_fimd0_set_platdata(nanopc_fb_pdata); 实际真正的数据是在nanopc_fb_pdata中并且在nanopc_fb_init_pdata中得到的值。 再看nanopc_fb_init_pdata这个函数发现以下几句 lcd tiny4412_get_lcd(); mode-left_margin lcd-timing.h_bp; mode-right_margin lcd-timing.h_fp; mode-upper_margin lcd-timing.v_bp; mode-lower_margin lcd-timing.v_fp; mode-hsync_len lcd-timing.h_sw; mode-vsync_len lcd-timing.v_sw; mode-xres lcd-width; mode-yres lcd-height; 数据实际来源于tiny4412_get_lcd()。 tiny4412_get_lcd定义在 arch/arm/mach-exynos/tiny4412-lcds.c中 到此我们终于找到各种屏的参数定义并且还有hdmi参数的定义。 待续