0 min

人眼对亮度的感知是非线性的,对暗处的变化比亮处的变化更敏感。如果图像没有进行 gamma correction,那么会分配了太多的比特来突出人类无法区分的亮点,并且分配了太少的比特显示阴影。因此需要 gamma correction 来校准,尽量做到线性化。 可以想象 video out 和 video in 之间的公式: $V_{out} = V_{in}^\gamma$ if gamma < 1, encoding gamma,称作 gamma compression。 if gamma > 1, decoding gamma,称作 gamma expansion。 蓝色为输入图像亮度变化曲线,红色为 gamma 值的曲线,紫色为最终显示的亮度变化曲线。 display gamma 即 lcd 运用的 gamma 变换,可以看出 gamma 的值在比如 0~255 色深中不是一个定值,通常需要 LUT 查找表来对某一范围内的亮度进行 gamma 变换。在 0~255 低位区域使用更小的 gamma,而高位区域使用更大的 gamma 值,gamma > 1。

1 min

Aggregate Driver 实现结构体: struct component_master_ops { int (*bind)(struct device *master); void (*unbind)(struct device *master); }; 在 probe 函数中调用 component_match_add()来填充 component match list, 最后调用 component_master_add_with_match() register aggregate driver, remove 函数中调用 component_master_del() 来 unregister。 void component_match_add(struct device *parent, struct component_match **matchptr, int (*compare)(struct device*, void*), void *compare_data) int component_master_add_with_match(struct device *parent, const struct component_master_ops *ops, struct component_match *match) Components Driver 实现结构体: struct component_ops { int (*bind)(struct device *comp, struct device *master, void *master_data); void (*unbind)(struct device *comp, struct device *master, void *master_data); }; 在 probe 函数中调用 component_add() register component driver, remove 函数中调用 component_del() 来 ungister。...

1 min

概述 bus 模块的功能包括: bus 的注册和注销 本 bus 下有 device 或者 device_driver 注册到内核时的处理 本 bus 下有 device 或者 device_driver 从内核注销时的处理 device_drivers 的 probe 处理 管理 bus 下的所有 device 和 device_driver 数据结构 struct bus_type { const char *name; const char *dev_name; const struct attribute_group **bus_groups; const struct attribute_group **dev_groups; const struct attribute_group **drv_groups; int (*match)(struct device *dev, struct device_driver *drv); int (*uevent)(const struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); void (*sync_state)(struct device *dev); void (*remove)(struct device *dev); void (*shutdown)(struct device *dev); int (*online)(struct device *dev); int (*offline)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); int (*num_vf)(struct device *dev); int (*dma_configure)(struct device *dev); void (*dma_cleanup)(struct device *dev); const struct dev_pm_ops *pm; bool need_parent_lock; }; name : bus 的名称....

2 min

struct device { struct kobject kobj; struct device *parent; struct device_private *p; const char *init_name; /* initial name of the device */ const struct device_type *type; const struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *platform_data; /* Platform specific data, device core doesn't touch it */ void *driver_data; /* Driver data, set and get with dev_set_drvdata/dev_get_drvdata */ struct mutex mutex; /* mutex to synchronize calls to * its driver....

2 min

dtc 工具和 fdtdump 工具: dtc –I dts –O dtb –o xxx.dtb xxx.dts dtc –I dtb –O dts –o xxx.dts xxx.dtb fdtdump -sd xxx.dtb > 1.txt # 有dtb header信息

1 min

数据结构 Platform 设备是可以通过 CPU bus 直接寻址的设备, 内核在设备模型 bus, device 和 driver 的基础上, 进行了进一步封装, 抽象了 platform_bus, platform_device, platform_driver. platform 相关的实现在 include/linux/platform_device.h, drivers/base/platform.c中. struct platform_device { const char *name; int id; bool id_auto; struct device dev; u64 platform_dma_mask; struct device_dma_parameters dma_parms; u32 num_resources; struct resource *resource; const struct platform_device_id *id_entry; }; name: platform device 的名称. dev: 指向底层的 device. id: 可以手动设置, 也可设置为宏 PLATFORM_DEVID_NONE 表示没有 id, pdev->dev->name 直接设置为 pdev->name. 设置为宏 PLATFORM_DEVID_AUTO 表示自动生成 id. id_auto: 当 id 设置为 PLATFORM_DEVID_AUTO, id_auto 被置为 true, 在注册 platform_device 时可以自动生成 id....

2 min

Data Structure struct dma_buf_ops { bool cache_sgt_mapping; int (*attach)(struct dma_buf *, struct dma_buf_attachment *); void (*detach)(struct dma_buf *, struct dma_buf_attachment *); int (*pin)(struct dma_buf_attachment *attach); void (*unpin)(struct dma_buf_attachment *attach); struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); void (*release)(struct dma_buf *); int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); int (*mmap)(struct dma_buf *, struct vm_area_struct *vma); int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); }; cache_sgt_mapping, ....

2 min

0 min

概述 include/linux/kobject.h lib/kobject.c Kobject 是基本数据类型,每个 Kobject 都会在"/sys/“文件系统中以目录的形式出现。 Ktype 代表 Kobject 的属性操作集合 (由于通用性,多个 Kobject 可能共用同一个属性操作集,因此把 Ktype 独立出来了). Kset 是一个特殊的 Kobject(因此它也会在"/sys/“文件系统中以目录的形式出现),它用来集合相似的 Kobject(这些 Kobject 可以是相同属性的,也可以不同属性的)。 数据结构 kobject: struct kobject { const char *name; struct list_head entry; struct kobject *parent; struct kset *kset; const struct kobj_type *ktype; struct kernfs_node *sd; /* sysfs directory entry */ struct kref kref; unsigned int state_initialized:1; unsigned int state_in_sysfs:1; unsigned int state_add_uevent_sent:1; unsigned int state_remove_uevent_sent:1; unsigned int uevent_suppress:1; }; name: kobject 的名称, 也是在 sysfs 中的目录名....

2 min