* It is impossible to get full supporting from 'configure'

Getting runtime informations - ex bytes of 'long' type, checking whether symbol 'xxx' is in the library or not. - is impossible.
-> Some releases complain this and doesn't proceed anymore.

* Some releases still refer /lib, /usr/lib, /usr/include etc.

* Using 'make check' in naive way is impossible.

* Anything else???

Java visibility는 private, protected, default(package private), public 이렇게 4단계가 있다.
그런데 개인적으로 한단계 정도 더 있었으면 한다.

기능별로 block을 형성하도록 programming할 수 있어야 한다. 그게 oop의 기본이기도 하다.
하나의 class가 하나의 block을 형성할 수 있으면 좋겠지만, 보통 여러개의 class가 하나의 기능 block을 형성한다.
그리고, 이 기능 block의 내부 interface는 package private으로 하고, 외부 interface는 public으로 둔다.
이게 Java에서의 일반적인 programming방법이다.
그런데, 어떤 기능 block 자체가 더 큰 기능 block의 한 부분이게 하고 싶은 경우는 어떻게 해야 하는가?
물론, 재 사용성을 위해서 모든 기능 블럭은 자체적으로 완벽하게 동작하도록 디자인하고, 관련 interface는 public으로 해 둘 수 있게 하는것이 이상적이긴 하다.
그렇지만, 대부분의 경우, 큰 기능 블럭의 한 부분임을 가정하고 programming하는 경우가 많다.
왜냐하면, 일반적인 기능블럭(public interface를 가지는...)을 만들어 내기 위해서는 추가적인 많은 노력들이 필요하기 때문이다.
그런데, Java의 visibility는 이런 경우를 해결해 줄 수 없다.
(하나의 package로 구성된 기능 block의 interface는 public이여야만 한다.)
그래서 개인적으로 추가적인 안을 제시해 본다.

*** tree-based name space ***

name space가 tree형태를 가진다. java convention을 이용해 설명하면, '.'을 separator로 하고, 각 name이 tree의 path를 의미하도록 하는 것이다.
예를 들면, 'com.java.io'라면, 'java'는 'com'의 child 이고, 'io'는 'java'의 child가 된다.

***  parent private ***

visibility가 자신의 parent에게만 되도록...

음.. visibility가 자꾸 많아지는 것도 안 좋긴 한데... 일단 이런게 있었으면 좋겠다... 단점도 있을 것 같은데.. 좀더 고민해 보자...

⚫ ueventd
    ⚬ ueventd creates and 'poll' netlink socket.
        ueventd_main [init/ueventd.c]

    ⚬ read kernel event message -> parse -> handle
        handle_device_event [init/devices.c]
            -> device_changed [init/init.c]
                -> queue_device_triggers [init/init_parser.c]
                            |
            +---------------+
            |
            v
        : search action list to know what to do for this event.
          searching action which name is device-added/removed-[device node].
          [device node] is from 'DEVPATH' variable of uevent message.

    ⚬ action list : list declared at [init_parser.c]
        • builtin action (added by 'queue_builtin_action [init/init_parser.c]')
            ex. property_init, wait_for_coldboot_done etc.
        • from script (added by 'parse_action [init/init_parser.c]')
            section "on device-added-[device path] / on device-removed-[device path]"
            ex.
                [init.rc]
                on device-added-/dev/block/mmcblk0p18
                    exec /system/bin/sh /system/bin/hello_mmc.sh

⚫ other daemons (ex usbd)
    ⚬ create and 'poll' netlink socket.
⚫ Sendig kobject uevent to user space from kernel
    ⚬ Concept
        • Execute user-space binary with predefined + customized environment variables.
        • Send message to pre-defined netlink socket unit created by kernel.

    ⚬ From souce code (hotplug)
        • kernel node [kernel/sysctl.c]
        : /proc/sys/kernel/hotplug

        • kobject_uevent_env() [kobject_uevent.c]
            default user process executable image path
                -> CONFIG_UEVENT_HELPER_PATH
        • kernel/sysctl.c
            'uevent_helper' value can be RWed through 'hotplug' node of sysctl.

    ⚬ From souce code (netlink)
        • kobject_uevent_env() [kobject_uevent.c]
            : #if defined(CONFIG_NET)
            write message to netlink socket unit (NETLINK_KOBJECT_UEVENT)
        • netlink.h
            netlink units
        • Creating in userspace
            socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
⚬ Concept
    - Creating Kernel Thread
    - Fork by call 'do_fork' directly (because, this is inside kernel!)
    - Exec by call 'do_execve'

⚬ Code walkthrough
    • kmod.h
        call_usermodehelper / call_usermodehelper_fns
            call_usermode_helper_setup(...)
            call_usermode_helper_setfns(...)
            call_usermodehelper_exec(...)

    • kmod.c
        call_usermode_helper_setup()
            -> setup subprocess infos.
                : path to execute, arguments, env variables etc
            -> set 'work' function of 'workqueue' to '__call_usermodehelper'
                : INIT_WORK(&sub_info->work, __call_usermodehelper);
        call_usermode_helper_setfns()
            -> setup subprocess functions
        call_usermodehelper_exec()
            -> queue this work to 'khelper_wq' workqueue.
        __call_usermodehelper() /* <- in work queue (khelper_wq) */
            pid = kernel_thread(___call_usermodehelper, sub_info, CLONE_VFORK | SIGCHILD);
        kernel_thread(...)
            : set pc to 'kernel_thread_helper'- assembly function
            pid = do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
        kernel_thread_helper
            : Shuffle the arument into the correct register before calling the thread function
            : set pc to given thread function (in this example, '___call_usermodehelper()' function.)
        ___call_usermodehelper()
            kernel_execve(sub_info->path, sub_info->argv, sub_info->envp);

    • sys_arm.c
        kernel_execve()
            do_execve(...)
            : make it to user space process!
codec을 재 설치해도, GOM player, KMP등을 지우고 재설치해도 해결이 안되었는데,
KMP를 실행하고 '컨트롤 박스..(Alt+G)'를 실행하니,  'COLORS' tab의 HW controls 부분에서 3개의 설정중 제일 위의 것이 가장 좌측으로 설정되어 있었는데, 이걸 중간으로 옮기니 문제가 해결되었다. 자세한 내용은 좀더 분석이 필요..~~~
(귀차니즘에... 과연 내가 더 분석을 하긴 할까나... -_-; )

'Domain > Win32' 카테고리의 다른 글

[Win32] Function Calling Convention  (0) 2008.12.03
[Win32][Tips] Creating Window...  (0) 2007.06.27
[Win32] IME Active중 VK Code얻기  (0) 2007.06.25
[Win32] 한글 입력하기  (0) 2007.06.23
[Tips] Cross-Compiling on Windows for Linux  (0) 2007.06.20

다음은  SW Engineer 경력 사원 기술 면접 내용 중 일부이다.
면접 진행은, 대화가 꼬리를 무는 문답 thread가 아니라 "질문->답" 형태였다.
즉, 지원자의 답에 따른 면접관의 이어지는 관련 질문이 없었다는 뜻이다.

(*1) C/C++에 자신이 있다고 하셨는데, 그렇다면 C++에서 'virtual'은 왜 존재하는가?
-> 몇번의 communication끝에, 위 질문의 정확한 의도는 "C++에서 virtual member function은 어떨때 쓰이고 왜 쓰이는가?" 였음이 밝혀졌고, 면접관이 요구한 답은 "base class로 type casting해서 사용할 때의 문제점을 해결하기 위한 방법" 이였다.

(*2) semaphore와 mutex의 차이는 무엇인가?

(*3) thread와 process의 차이는 무엇인가?

(*4) singleton 은 무엇인가?

* 기타 등등...

난 개인적으로 위의 질문들의 수준이 높다고 보지는 않는다. 물론 이건 전적으로 내 개인적인 생각이므로 보는 사람에 따라 다를 수 있다는 것은 인정한다.
따라서 쓸데없는 딴지는 사양한다. 전부 내 개인적인 생각이니까..

그럼 왜 위의 질문들이 소위 "수준 높은 질문"이 될 수 없는가? 인터넷에서 10분만 검색해 보면 전부 답을 알 수 있는 내용들이기 때문이다.
물론 위의 질문들을 통해서 턱없이 부족한 실력의 지원자를 골라낼 수도 있겠다.
그렇지만, SW engineer의 경력분야에 따라서 실질적인 내용은 전부 알고 있음에도 불구하고, 위의 질문들에 제대로 대답하지 못하는 경우도 발생할 수 있다.

예를 들어, low tier embedded분야에서만 장시간 일해온 사람이라면, singleton 이라는 design pattern의 용어는 생소하게 들릴 것이다.

또한, context간 - 굳이 thread라는 용어를 사용하지 않았다. 왜냐하면, 'task'라는 용어 역시 가끔 'thread'와 동일 개념으로 사용되기도 하기 때문이다. - 동기화에 대해서는 잘 알고 있지만, semaphore와 mutex의 차이 역시  별 관심이 없을 수도 있다.
그냥 interrupt disable/enable로 동기화를 해야하는 SW system에서 일해 왔을 수도 있기 때문이다.
즉, '동기화' 라는 실질적인 내용은 잘 알고 있지만 - 사실 이 부분이 핵심이다 - 'semaphore'라든가 'mutex'라는 용어에 익숙치 않을 수도 있다는 뜻이다.
이는 그 사람의 지식 체계가 'semaphore'와 'mutex'를 사용하는 곳에서 쌓여진 것이 아니라, interrupt disable/enable을 사용하는 '체계'이기 때문이다.

마지막으로, 위의 면접형태의 가장 큰 문제점은, 계속되는 문답을 통한 지원자의 실질적인 지식을 측정하지 않고, 질문에 대한 정답을 요구하는 '주관식 시험 문제'와 같은 형태라는 것이다.
따라서, 그 사람의 실질적인 기술 지식(용어를 많이 안다는 것을 뜻하는게 아니다,) + 지식체계를 판단하기에는 다소 미흡하다고 생각한다.

위의 질문들은, 뛰어난 실력에도 불구하고 위에서 사용된 용어들과 맞지 않는 지식체계를 가진 사람들을 배제시킬 가능성이 있다.
또한, 실질적인 내용은 잘 모르고 용어의 뜻만 알고 있는 사람을, 실질적인 내용을 알고 있는 사람으로 오해할 여지도 있다.
그렇다면 어떤식으로 질문이 이루어져야 하는가? 위의 질문들을 가지고 다시 한번 재구성해 보자.

먼저 위의 질문은 크게 *1, *4  (A 그룹) 그리고 *2, *3  (B 그룹) 두 가지로 분류할 수 있고, 각 그룹은 하나의 문답 thread로 연결 시킬 수 있다.
필자가 생각하는, 각 그룹에 대한 문답 thread는 아래와 같다.

[ A그룹 ]

* SW architecture design에서 중요한 것들은 어떤 것들이 있을까?
-> 대화중, 모듈화나 information hiding에 대한 이야기를 유도한다.

* information hiding에 대해서 이야기 해 보면?
-> 여기서, "interface와 implementation의 분리"에 대한 이야기를 이끌어 낸다.

* interface와 implementation의 분리를 실제로 어떤 식으로 구현할 수 있을까? C++를 잘 안다고 했는데, C++를 예로 설명해 보면?
-> 이때, 상속, 다형성 등의 이야기가 나올 것이고, 자연스럽게 'virtual' 에 대한 이야기를 끄집어 낼 수 있다. 또한 instantiation에 대한 이야기도 이끌어 내도록 하자.

* 특정 class/모듈에 대해서는 instance를 여러개 만드는 것을 막고 싶은데 어떻게 하면 될까?
-> singleton에 대한 이야기를 끄집어 낼 수 있다. 이때, singleton이라는 용어를 알고 모르고는 중요하지 않다. 실질적인 내용과 개념을 정확히 알고 있는지 파악하는게 중요하다.

* 계속진행...
(각종 design pattern에 대한 이야기들, C++이 아니라 C에서 구현하는 design pattern의 개념들 - C로 상속, singleton, 다형성의 구현 등 -  등으로 이야기를 진행시킬 수 있다.
사실 C로 information hiding, OOP의 개념들을 구현하는 것에 대한 대화는, 해당 분야에 대한 지원자의 이해도를 측정하기에 굉장히 좋은 방법 중에 하나이다.)

[B 그룹]

* OS란 무엇인가? OS의 가장 핵심이 되는 기능은 무엇인가?
-> context관리에 대한 이야기를 끄집어 낼 수 있다. 혹은 대부분의 경우, 이미 thread와 process라는 용어가 등장했을 것이다.

* 무엇이 thread고 무엇이 process인가?
-> 사실, 위의 질문 자체는 괜찮은 시작점이 될 수 있었다. 문제는 이어지는 후속 질문들이 없었다는 것이다.

* 어떤 경우 thread/process를 사용해야 할까? 각각의 장단점은?
-> context switching, scheduling등의 개념과 더불어,  race condition에 대한 이야기를 끄집어 낼 수 있다.

* race condition문제는 어떤식으로 해결해야 할까?
-> 이때, context간 동기화에 대한 이야기를 이끌어 내면서, semaphore, mutex 등의 개념의 이해를 판단할 수 있다.

* 계속 진행... (deadlock, mutex의 구현 방법 (atomic instruction, interrupt disable/enable), Out-of-order optimization, Memory Barrier 등등으로 이야기를 계속 진행시켜 나갈 수 있다.)

이런 식으로 대화를 진행하면, 단지 용어만을 알고 있는 어설픈 실력자를 구별해 내면서, 지원자의 실질적인 지식과 지식 체계까지 파악할 수 있다.
면접관이 지원자에게 하는 질문의 이상적인 형태는 소크라테스의 '문답법'과 같아야 한다고 생각한다.
지원자의 대답과 거기에 이어지는 꼬리를 무는 질문들... 이런 식의 질문이 정말 "제대로 된 면접 질문" 이라고 생각한다.
물론, 동의하는 사람도 있고... 그렇지 않은 사람도 있겠지만... -_-;

이제 이 문제를 조금 더 확장해 보도록 하겠다.

보통 면접관은 지원자의 '대답'을 통해서, '질문'이 의미하는 특정 분야에 대한 지식/역량/기술을 알아보고자 한다.
그래서 일반적인 면접은 "질문(면접관)->대답(지원자)"이 연속하는 과정이다.
그런데 무언가 빠진 것 같지 않은가?
이런 과정에서는 '지원자' 가 어떤 것에 관심이 있고, 어떤 것을 중요하게 생각하는지는 알 수 없다.
어떤 사람과 함께 일하기 위해서는 그 사람의 관심분야,  중요하게 생각하는 분야, 가장 잘 하는 분야 등도 굉장히 중요한 고려사항이다.
비록 지금 당장 필요한 부분의 역량은 조금 부족하다고 생각되는 지원자라도, 의외로 다른 중요한 부분에서 굉장한 두각을 나타낼 수도 있기 때문이다.
물론, 단도직입적으로 "당신은 어떤 분야에 관심이 있나요?" 혹은 "어떤 분야를 잘 할 수 있나요?"라는 추상적인 질문을 통해 이를 파악할 수도 있을 것이다.
그렇지만, SW는 엄청나게 많은 분야에 걸쳐 세분화 되어 있으므로, 추상적인 "질문 -> 대답" 으로 명확한 답을 얻기란 쉽지 않다.
예를 들면, "전 OS에 관심이 있습니다."라는 대답하는 지원자가 있다고 가정하자.
이 대답으로 '관심분야'와 '중요하게 생각하는 분야'에 대한 파악이 다 되는가?
아마도 추가적으로 "OS중에 구체적으로 어떤 분야에 관심이 있나?" 식의 추가적이고 연속적인 질문이 뒤따라야 할 것이다.
그리고 대부분의 경우 이런 추가적인 질문들을 통해서도 원하는 만큼의 관련 정보를 얻기는 쉽지 않을 것이다.

다시 한번 정리해 보자.
일반적으로 사용되어지는 "질문(면접관) -> 대답(지원자)"의 면접 방법은 "면접관이 관심있고, 중요하게 생각하는 분야에 대한 지원자의 역량을 파악하기 위함"이라고 봐도 좋다.
그런데, 이 과정은 "지원자의 관심/중요 분야, 그리고 지원자가 가장 잘 할 수 있는 분야에 대한 파악"에는 적합하지 않다.

여기서 난 다음과 같은 방법을 제안해 본다. (아직 개인적으로 시험해 볼 기회가 없었기 때문에 실제적인 '실험(?)' 결과는 제시할 수 없지만, 기회가 되어서 실질적으로 적용해 볼 기회가 생기면 결과를 추가적으로 기재하도록 하겠다.)

"지원자 스스로가 질문하고 대답하는 것이 주(main)가 되고, 면접관의 질문은 이를 조정(control)하는 역할을 하는 면접"

(예) <지원자(홍길동) 에 대한 기술 면접>
홍길동씨 자신이 면접관이라고 생각하고, 자기 자신과 같이 일할 사람을 뽑는 다고 생각합시다.
그리고, 홍길동씨가 면접볼 사람은 홍길동씨 자신힙니다.
다시 말하면, 홍길동씨 스스로가 질문하고 대답하는 것입니다.
시작해 볼까요.

어떤가?
면접관이 다양한 분야 충분한 기술적인 지식이 있다면 위와 같은 면접은 기술적인 분야에서 지원자의 성향/가치관/비젼 등에 대한 세세한 파악을 가능하게 해 준다.
그리고, 문답의 진행 분야/방향 역시 지원자의 역량을 파악하기 위한 중요한 정보가 될 수 있다.
만약 문답의 진행이 엇나가거나, 면접관이 생각하기에 무언가 부족한 부분이 있다면(면접관이 꼭 알아보고 싶은 분야가 빠졌다던가...), 진행 중간에 이를 조정해 주면 된다.
단, 이때에도 구체적인 질문의 형태를 통해서 이를 조정하고자 하면 안된다.
예를 들면, thread 동기화에 관한 '문답'이 진행되고 있는데, 이 과정에서 'deadlock'에 대한 내용이 빠져 있고, 이를 알아볼 필요가 있다고 면접관이 생각한다면,
"deadlock 에 대한 부분은 어떻게 생각합니까?"
라는 지원자의 직접적인 '답'을 유도하는 질문 보다는
"무언가 빠진거 같은데, 동기화 관련해서 몇몇 문제들이 있지 않나요? 거기에 관련해서 지원자의 역량을 좀더 파악해 보도록 합시다."
라는 식으로, 관련 분야에 대해서 지원자가 다시 '질문 -> 답'의 과정을 시작할 수 있게 해 주어야 한다.
즉, 면접관에 대한 지원자의 반응이 '답'으로 끝나는 형태의 조정이 아니라, 지원자 자신에 대한 '질문 -> 답'이 되는 형태의 조정을 해 주어야 한다.
주제를 바꿀 때도 마찬가지다.
"이제 OOP에 대한 주제로 바꾸어 봅시다. "
식으로 '문답'을 유도해 나가면 된다.

단, 이런 식의 면접은 다양한 분야에 충분한 양의 기술적인 지식을 가진 면접관을 필요로 한다.
특정 분야에 편중된 지식을 가진 면접관의 경우, 이런 식의 면접은 오히려 시간 낭비가 될 수 있다.
운이 좋아서 지원자의 '문답' 진행 방향과 면접관의 지식 분야가 일치하면 더 없이 좋겠으나, 그렇지 않은 경우는 그냥 일반적인 '질문(면접관) -> 대답(지원자)'와 별반 다를 게 없어진다.

괜시리 이야기가 길어졌는데...
어쨌든... 일단 내 개인적은 경험/생각 에서 정리된 내 나름대로의 방법을 정리해 보았다.
음... 실제로는 어떤 결과를 보여줄지 궁금하기도 하고...
기회가 되면 꼭 이 방법을 적용해 보리라...

This article is to describe summary and some important points to establish gnu system root on android devices based on my experience.

Notation
    [] : version used.

===============
Introduction
===============
    Now a days, performance of Android mobile device is much like PC.
    So, why don't you use Android device just like linux desktop?
    As a first step, here is summary to construct gnu system root on Android device.

==============
Setup Sequence
==============
    Installing cross compiling tools
    ----------------------------------------------------------------------
        *** NOTE ****************************************************************
        *    Followings are not tested because I just used built Sourcery g++.  *
        *    [ Codesourcery 2007q3-53 ]                                         *
        *************************************************************************
        * Reference : http://frank.harvard.edu/~coldwell/toolchain/
        * Build GNU binutils
            - Using '--disable-nls' option is recommended (to reduce compile time and dependency.
        * Install Linux Kernel Headers
            - Latest Sourcery g++(2010.09-50) supports only at-least-2.6.16-target-kernel.
        * Build GLIBC headers
        * Build GCC for headers:
            - Using '--disable-nls --without-headers' is recommended.
            - example : configure option of GCC in Codesourcery 2007q3-53
                /vobs/linuxjava/cs_toolchain/mycstc/cs_build_dir/src/gcc-4.2/configure --build=i686-pc-linux-gnu
                  --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap
                  --disable-libssp --disable-libgomp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld
                  --enable-languages=c,c++ --enable-shared --enable-symvers=gnu --enable-__cxa_atexit
                  --with-pkgversion=CodeSourcery Sourcery G++ Lite 2007q3-53
                  --with-bugurl=https://support.codesourcery.com/GNUToolchain/
                  --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc
                  --with-build-sysroot=/vobs/linuxjava/cs_toolchain/mycstc/cs_build_dir/install/arm-none-linux-gnueabi/libc
                  --enable-poison-system-directories
                  --with-build-time-tools=/vobs/linuxjava/cs_toolchain/mycstc/cs_build_dir/install/arm-none-linux-gnueabi/bin
                  --with-build-time-tools=/vobs/linuxjava/cs_toolchain/mycstc/cs_build_dir/install/arm-none-linux-gnueabi/binff
        * Build GLIBC libraries
        * Rebuild GCC using newly-built-GLIBC.

    Construct gnu system root
    -------------------------
        * Environments
            # this directory will be new gnu system root on Android target.
            PREFIX=/data/arm-gnu-sysroot/
            # gnu root directory on target device
            TGNUROOT=/data/gnuroot/
            TARGET=arm-none-linux-gnueabi
            export ARCH=arm
            export CROSS_COMPILE=${TARGET}-
            # set PATH
            PATH=<cross-tools>:$PATH
        * Install headers and GLIBC
            - copy cross-compiled glibc, headers etc to $TROOT except for i686 executables and related files
        * Build GNU binutils [binutils-2.18]
            - ./configure --prefix=${PREFIX} --host=${TARGET} --target=${TARGET} --disable-nls
        * Build GCC [gcc-4.2.1]
            - ./configure --prefix=${PREFIX} --build=i686-pc-linux-gnu --target=${TARGET} --host=${TARGET}
                --disable-nls --enable-languages=c
        * Build bash [bash-4.0]
            - ./configure --prefix=${PREFIX} -host=${TARGET} --without-bash-malloc
            - install to $PREFIX/bin. And link $PREFIX/bin/sh to $PREFIX/bin/bash
        * Build gnu make [make-3.82]
            - ./configure --prefix=${PREFIX} -host={TARGET}
        * Build busybox
            - Set cross compiler prefix to 'arm-none-linux-gnueabi-' and make.
            - install to $PREFIX/bin
              (usually commands in busybox are located at /bin)
            - create link to busybox for each command.
        * copy to target device
            - adb push $PREFIX $TGNUROOT
        * link rootfs to gnu system root.
            - ln -s $TGNUROOT/lib /lib
            - ln -s $TGNUROOT/bin /bin
              ...

===============
Confirm & Check
===============
    Build Emacs-23.2
    ----------------
        * push Emacs-23.2 source code to target.
        * ./configure --without-xpm --without-jpeg --without-tiff --without-gif --without-png --without-rsvg
             --without-xft --without-libotf --without-m17n-flt --without-toolkit-scroll-bars --without-xaw3d
             --without-xim --without-gpm
        * 'make' should be done without error.

    Running Emacs
    -------------
        * copy termcap.src from "http://www.opensource.apple.com/source/emacs/emacs-39/emacs/etc/termcap.src".
          And put this /usr/etc/termcap.src.
        * And set following environment variable
            TERM=linux
            TERMCAP=/usr/etc/termcap.src
        * Emacs should work without error in 'adb shell' terminal.

===============
NOTE
===============
    Points
    ------
        * headers and GLIBC built for cross-compiling should be used as they are at target system root.
          (To use cross-compiled binaries on target device without any potential issues.)
        * Some open source packages check only /lib and /usr/lib (/usr/local/lib isn't considered).
          So, fundamental libraries would be better to be installed at /usr/lib,
         even if it's default location is /usr/local/lib

Setting up gnu system root is the first step to construct gnu software stack on the system.
And, now it's done.
So, next step is installing packages to set up development-friendly environment on the Android device.
Below description is summary of issues that I faced against during installing gnu packages.

* Executing /usr/bin/su doesn't run ~/.bashrc
    ~/.bashrc is not executed if user shell is set up as /bin/sh, even if /bin/sh is just symbolic link of /bin/bash.
    Let's assume that /bin/sh -> /bin/bash.
    In this case, executing /bin/sh means "run bash as just 'shell' - sh".
    So, to make ~/.bashrc be run automatically, default shell of user should be set as /bin/bash not /bin/sh

* default .bashrc of normal(ex. ubuntu) desktop PC can be used as a template in Android device.

* terminal editor programs - vi, nano, emacs etc - don't work or work abnormally.
    Environment related with 'Terminal' should be set correctly.
        - Environment variables
            export TERM=xterm
            export TERMINFO=/etc/terminfo
            export TERMCAP=/etc/termcap
    Related files at /etc
        terminfo
            this has setting values for various terminal types - linux, vt100, xterm and so on.
            /etc/terminfo of desktop linux PC can be used as it is.
        termcap
            this is required by emacs.
            termcap.src(included at termcap source release) can be used as /etc/termcap.

* mode of newly created file becomes 0666 or 0777.
    umask should be set at .bashrc .
        umask 022

* window of editor programs like vi, emacs is default screen size (80x24)
 even if real screen size of terminal emulator is bigger.
    resize command should be executed.
    putting it at .bashrc is recommended.
    this command sets environment variables - COLUMNS and LINES - according to current terminal window size
   and export it.

* various colors are not used at the output of ls command.
    check that dircolors command is installed and this command is set correctly at .bashrc

* sudo command doesn't give any chance to enter password. It only says "Sorry, try again.".
    pam is not correctly binded with sudo.
    install /etc/pam.d/sudo file.
    (sample.pam included at sudo source code release can be a good reference.
     - especially, second option - use pam_unix - is recommended)

* icmp protocol is not recognized by ping - included at inetutils - command.
    check /etc/protocols file is correctly installed.
    this file can be used by copying desktop's one.

* localhost is not recognized even though ip address - 127.0.0.1  - works well.
    check followings at /etc/hosts
        127.0.0.1    localhost
    check below line at /etc/nsswitch.conf (related with nameserver)
        hosts: files dns

Anything to do?

This is due to flow control.
C-s and C-q is reserved key sequence for flow control.
So, by disabling it - just type 'stty -ixon' - you can use C-s and C-q key sequence.

RnR(Role and Responsibility)데 대한 정의는 공동업무를 진행하는 과정에서 꼭 필요한 부분이다.
SW 실무적으로 RnR를 정의하는 방법은 크게 두가지로 나뉠 수 있을 것 같다.

첫번째, 기능별 분류이다. (a)
Multimedia Engine, Multimedia Application, GPS, Call 등등으로 구분하는 것이 대표적인 방법이다.
내가 생각하기에 현재 대부분의 SW연구소가 택하는 방법이 아닌가 한다.

두번째, 물리적인 file/directory 단위의 구분이다. (b)
Linux Kernel을 예로 들면, /mm, /kernel, /sound 등의 단위로 나누는 것이다.
이 방법은 몇몇 특수한 경우에만 사용하는 것으로 일반적이지는 않는 것으로 알고있다.

위 두가지 방법을 간단하게 비교해 보자.
먼저 (a)의 경우다.
장점: 특정 기능별로 구분되어 있으므로 해당 분야의 domain knowledge를 쌓아 전문가를 양성하기 좋다. 따라서 해당 분야에 대한 장기적인 성장에 유리하다.
단점: SW code의 물리적인 위치가 기능별로 명확히 구분되어 있지 않고, common한 부분이 많은 경우 (보통의 효율적이고 well-structured 된 code 일 수록  code 공유/재사용 이 많다.) RnR에 대한 논란의 여지가 많다. 따라서, 이로 이한 팀/개인 간의 갈등, communication overhead, 비협조적인 업무진행 등의 문제를 만날 수 있다.

(b)의 경우 (a)와 정확히 반대 된다.
같은 기능이라도 여러 팀이 관여하게 되므로, 업무 진행시 실무자간 제법 많은 양의 communication을 필요로 한다.
Camera 기능을 예로 들어보자.
Camera의 경우, Sensor Driver, HAL(Hardware Abstraction Layer), Application Framework, Application등에 그 기능이 걸쳐 있을 것이다.
따라서 Sensor에서 지원해 주는 특정 기능을 구현하기 위해서는 각 directory (아마도, driver, HAL, FW, App은 각각 다른 directory에 위치해 있을 것이다.) 별 owner들간 많은 대화가 필요할 것이다.

경우에 따라 다르겠지만, 비교/분석해 봐야할 대상은 명확해 진듯 하다.
"RnR의 불확실성에 따른 문제로 인한 업무 비용" vs. "기능별 SW업무시 발생할 수 있는 file/directory owner들 간 communication에 따른 비용"
(a)의 경우는 이미 많이 겪어 봤다. (b)는 아직 경험해 보지 못했다.
과연 어느 쪽어 더 효율적일까? (산업/업무 문야에 따라 다르겠지만...)

+ Recent posts