자두맛쭝이 2011. 4. 15. 10:45

/system/core/rootdir/init.rc

   

Android Init Language로 기술 되어 있음 ( /system/core/init/readme.txt )

   

  • action

       

    on <trigger>

    <command>

    <command>

       

  • service & option

       

    service <name> <pathname> [ <argument> ]*

    <option>

    <option>

    ...

       

    모든 서비스는 parse_line_service 에서 파싱 되어 동작 한다. ( /system/core/init/parser.c )

       

example)

   

  • Socket

       

    socket <name> <type> <perm> [ <user> [ <group> ] ]

    Create a unix domain socket named /dev/socket/<name> and pass

    its fd to the launched process.  <type> must be "dgram" or "stream".

    User and group default to 0.

    -> /dev/socket/ 에 <name> 이름을 가진 Unix Domain Socket 을 만들고 실행한 프로세스에게 fd 를 넘긴다

        <type> 은 반드시 dgram 이나 stream 이어야 한다. User 와 group (의 권한)은 기본적으로 0

       

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

    socket zygote stream 666

    onrestart write /sys/android_power/request_state wake

    onrestart write /sys/power/state on

    onrestart restart media

       

       

    // 추후 내용 보충

    dgram - UDP, 비 연결형 ( 보장 x )

    stream - TCP, 오버헤드, 신뢰

       

    • 소켓 정보 설정 - parse_line_service ( /system/core/init/parser.c )

       

    args[0] - socket / args[1] - xxx / ….

       

    // 소켓 정보 셋팅

    si->name = args[1];

    si->type = args[2];

    si->perm = strtoul(args[3], 0, 8);

    si->next = svc->sockets;

    svc->sockets = si;

       

    • 소켓 생성 및 fd 값 저장 - service_start ( /system/core/init/init.c )

       

    for (si = svc->sockets; si; si = si->next) {

    /*

    /dev/socket/'si->name' 의 파일로 바인딩 된 unix domain socket 생성 후 fd 리턴

    */

    int s = create_socket(si->name,

    !strcmp(si->type, "dgram") ?

    SOCK_DGRAM : SOCK_STREAM,

    si->perm, si->uid, si->gid);

    /*

    publish_socket - ( key, value ) 환경 변수 생성

    key - ANDROID_SOCKET_ + si->name

    key 와 생성 된 fd 매핑

    */

    if (s >= 0) {

    publish_socket(si->name, s);

    }

    }

       

   

  • command

       

exmple)

   

  • mount

       

    mount <type> <device> <dir> [ <mountoption> ]*

    Attempt to mount the named device at the directory <dir>

    <device> may be of the form mtd@name to specify a mtd block

    device by name.

    <mountoption>s include "ro", "rw", "remount", "noatime", ...

       

    mount /mnt 0775 root system

       

    ( /system/core/init/parser.c )

    • 커맨드 맵핑

      static void parse_line_action(struct parse_state* state, int nargs, char **args)

      {

      /*

      ( /system/core/init/keywords.h )

      keyword 와 func 정의 되어 있음

      */

      kw = lookup_keyword(args[0]);

      /*

      필요한 정보 저장

      */

      cmd->func = kw_func(kw);

      cmd->nargs = nargs;

      memcpy(cmd->args, args, sizeof(char*) * nargs);

      list_add_tail(&act->commands, &cmd->clist);

      }

         

    • 맵핑 된 커멘드 호출

         

      void action_for_each_trigger(const char *trigger,

      void (*func)(struct action *act))

      {

      struct listnode *node;

      struct action *act;

      list_for_each(node, &action_list) {

      act = node_to_item(node, struct action, alist);

      if (!strcmp(act->name, trigger)) {

      func(act); // call do_mount() - ( /system/core/init/builtns.c );

      }

      }

      }

       

  • trigger

       

    <name>=<value>

    Triggers of this form occur when the property <name> is set

    to the specific value <value>.

       

example)

   

  • on Property

       

    on property:ro.kernel.qemu=1

    start adbd

       

    ro.kernel.qemu 가 1로 셋팅 되면 'start adbd' 실행

       

    • property 변경 시 property_set_fd 의 events POLLIN에 의해

      handle_property_set_fd(property_set_fd) 호출

      참고 - init.c 18, 19

         

    • handle_property_set_fd() -> property_set() -> property_changed()

      ( /system/core/init/property_service.c )