ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2014年6月23日 星期一

build.prop 中的 property 在哪一個階段可以開始使用..

很多人很喜歡在 build.prop 中加東西。

build.prop 在 bionic/libc/include/sys/_system_properties.h :  #define PROP_PATH_SYSTEM_BUILD "/system/build.prop"

然後在 system/core/init/ 中ref...
void start_property_service(void)
{
    int fd;

    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
    load_override_properties();
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();

#ifdef HAVE_SELINUX
    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0, NULL);
#else
    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
#endif
    if(fd < 0) return;
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    fcntl(fd, F_SETFL, O_NONBLOCK);

    listen(fd, 8);
    property_set_fd = fd;
}

然後是在init.c :
static int property_service_init_action(int nargs, char **args)
{
    /* read any property files on system or data and
     * fire up the property service.  This must happen
     * after the ro.foo properties are set above so
     * that /data/local.prop cannot interfere with them.
     */
    start_property_service();
    return 0;
}
在 init 的 main process 中,可以看到啟動的順序:
    INFO("reading config file\n");
    init_parse_config_file("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");

    /* execute all the boot actions to get us started */
    action_for_each_trigger("init", action_add_queue_tail);

    /* skip mounting filesystems in charger mode */
    if (!is_charger) {
        action_for_each_trigger("early-fs", action_add_queue_tail);
        action_for_each_trigger("fs", action_add_queue_tail);
        action_for_each_trigger("post-fs", action_add_queue_tail);
        action_for_each_trigger("post-fs-data", action_add_queue_tail);
    }

    queue_builtin_action(property_service_init_action, "property_service_init");
    queue_builtin_action(signal_init_action, "signal_init");
    queue_builtin_action(check_startup_action, "check_startup");

    if (is_charger) {
        action_for_each_trigger("charger", action_add_queue_tail);
    } else {
        action_for_each_trigger("early-boot", action_add_queue_tail);
        action_for_each_trigger("boot", action_add_queue_tail);
    }

        /* run all property triggers based on current state of the properties */
    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
所以在 build.prop 中的設定值,在 signal_init 階段後,就可以使用了。


其實從 code 來看,各個 prop 的順序是..
  • /default.prop
  • /system/build.prop
  • /system/default.prop
  • /data/local.prop
看 /system/default.prop 的產生經過...
在 android/build/ 中...依照 product_name, 會有一堆...

2014年6月20日 星期五

of_property_read_string

Linux 3.0 後新增的 DTB, 其中,string 的 property 用 of_property_read_string

在 /driver/of/base.c:
/**
 * of_property_read_string - Find and read a string from a property
 * @np:  device node from which the property value is to be read.
 * @propname: name of the property to be searched.
 * @out_string: pointer to null terminated return string, modified only if
 *  return value is 0.
 *
 * Search for a property in a device tree node and retrieve a null
 * terminated string value (pointer to data, not a copy). Returns 0 on
 * success, -EINVAL if the property does not exist, -ENODATA if property
 * does not have a value, and -EILSEQ if the string is not null-terminated
 * within the length of the property data.
 *
 * The out_string pointer is modified only if a valid string can be decoded.
 */
int of_property_read_string(struct device_node *np, const char *propname,
    const char **out_string)
{
   struct property *prop = of_find_property(np, propname, NULL);
   if (!prop)
      return -EINVAL;
   if (!prop->value)
      return -ENODATA;
   if (strnlen(prop->value, prop->length) >= prop->length)
      return -EILSEQ;
   *out_string = prop->value;
   return 0;
}
這個 function 只是把 DTB 中該 string 的位置 return 出來。
所以傳入的 pointer 不必預先 allocate 空間,
同樣的,return 回來後,也不能修改內容。

2014年6月17日 星期二

raspberry pi, 更改 keyboard layout

裝完官方 wheezy image 後,keyboard 的 layout 是英國的,所以打 '|' 會出現 '~'

修改的方式,就是手動 edit /etc/default/keyboard
其中有一行:
 XKBLAYOUT="gb"
改成
 XKBLAYOUT="us"
然後重開機就可以了。

2014年6月12日 星期四

device tree , arm and linux

linux 3.0 以後。ARM 也開始使用 Device Tree.

各platform , chip 的 device tree 寫在 arch/arm/boot/dts

build kernel 時,kernel 與 dts file 會分開 build.
dts 會用 device tree compile compile 成 DTB 檔。

bootloader 啟動 kernel 時,會同時把 DTB 讀入記憶體,交給 kernel.
kernel 啟動後,在 arch/arm/kernel/setup.c : setup_arch( ) 中
unflatten_device_tree();
負責把 DTB 解成 device tree 結構。

driver/of/fdt.c:
/**
 * unflatten_device_tree - create tree of device_nodes from flat blob
 *
 * unflattens the device-tree passed by the firmware, creating the
 * tree of struct device_node. It also fills the "name" and "type"
 * pointers of the nodes so the normal device-tree walking functions
 * can be used.
 */
void __init unflatten_device_tree(void)
{
 __unflatten_device_tree(initial_boot_params, &of_allnodes,
    early_init_dt_alloc_memory_arch);

 /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
 of_alias_scan(early_init_dt_alloc_memory_arch);
}


ref:
  • http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
  • http://blog.csdn.net/21cnbao/article/details/8457546
  • https://sites.google.com/site/yucheng1102/linux-kernel/device-tree
  • http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9

標籤

網誌存檔