리눅스/커널2014. 3. 31. 10:14

early_param("HI_MEM", HI_MEM_Init) 

  --> __setup_param(str, fn, fn, 1) 으로 정의되어 있는데 이를 자세히 보면,

static const char __setup_str_##unique_id[] __initcost \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
  __used __section(.init.setup)
  __attribute__((aligned((sizeof(long))))) \
  = { __setup_str_##unique_id, fn, early }


long 사이즈로 align된 .init.setp섹션에 obs_kernel_param 구조체 형태의 __setup_##unique_id 안에 { __setup_str_##unique_id, fn, early } 형태로 초기화 시킨다. 


obs_kernel_param 구조체는 

const char *str
int (*setup_func)(char *);
int early;

로 구성되어 있다.

이렇게 설정된 early_param의 내용은 init/main.c에서 parse_early_options() --> parse_args("early options", cmdline, NULL, 0, do_early_param) --> parse_one()안에서
return handle_unknown에서 do_early_param이 실행된다.

do_early_param을 실행시킬 때, 그동안 쌓인 obs_kernel_param 리스트(?)들을 순회하면서 실행 시킨다.(섹션에 구조체가 리스트로 들어가기 보다는 각각의 구조체가 엔트리로 들어가는 거 같은데 좀 더 확인이 필요하다.)


__setup_start[] 와 __setup_end[]는 include/asm-generic/vmlinux.lds.h 에서 다음과 같이 정의되어 있다.


#define INIT_SETUP(initsetup_align) \ . = ALIGN(initsetup_align); \ VMLINUX_SYMBOL(__setup_start) = .; \ *(.init.setup) \ VMLINUX_SYMBOL(__setup_end) = .;

또한 INIT_SETUP은 arch/arm/kernel/vmlinux.lds.S에서 16byte(?)으로 align되어 있다.

.init.data : { #ifndef CONFIG_XIP_KERNEL INIT_DATA #endif INIT_SETUP(16) INIT_CALLS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS }


좀 더 자세히 봐야 하는데, 결국 맨 위, "HI_MEM"이라는 parameter에 대한 처리를 HI_MEM_init에서 처리할 수 있게 된다.


'리눅스 > 커널' 카테고리의 다른 글

Machine 이름 바꾸기  (0) 2014.04.03
Machine 이름 알아내기  (0) 2014.04.03
/dev/tty 와 /dev/console의 차이점  (0) 2014.02.05
FrameBuffer size 구하기  (0) 2013.12.11
[커널] FB 문서  (0) 2013.12.09
Posted by code cat
리눅스2014. 3. 14. 08:44


--sysroot=dir
Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches dir/usr/include and dir/usr/lib.

If you use both this option and the -isysroot option, then the --sysroot option applies to libraries, but the -isysroot option applies to header files.

The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the header file aspect of --sysroot still works, but the library aspect does not. 


sysroot 는 컴파일 시에 필요한 header/lib 들을 찾는 경로에 대한 베이스 경로를 지정해 줄 수 있다.

여러가지 용도로 사용할 수 있겠으나, 다음과 같은 경우에 우선 쓸 수 있다.

1. gdb 로 디버깅 시, 타깃머신(gdbserver가 동작중)의 라이브러리들이 소스머신(gdb 동작중)의 라이브러리들과 매칭이 되지 않을 때.

2. toolchain이 소스와 제공(android경우)되어 그 toolchain을 써야 하나, bionic libc에서 지원하지 않는 라이브러리 함수를 어플리케이션이 사용해야 할 때.


위의 노란 부분은 gcc에서 sysroot 사용법에 대한 설명이다.  --sysroot=dir을 설정하면, 컴파일러께서는 dir/usr/include, dir/usr/lib 등으로 찾으신다.

Posted by code cat
프로그래밍/C++2014. 2. 19. 08:51

jump to case label -fpermissive


라고 나오는 에러는 흔히 switch-case문에서 case안에서 변수 선언 & 초기화를 할 때 나올 수 있는 문제이다.  이는 언어에서 정한 standard를 벗어난 경우이며, -fpermissive를 써서 호환가능하게 해 줄 수는 있지만, 쓰지 말고, 코드를 fix하는 방향으로 가도록 하자.


'프로그래밍 > C++' 카테고리의 다른 글

[c++] UML autogenerator  (2) 2015.03.23
생성자 호출 방법  (0) 2015.03.19
[template]템플릿 예제  (0) 2013.08.04
null pointer vs stray pointer  (0) 2013.05.26
[c++] malloc/free 대신 new/delete을 쓰는 이유?  (0) 2013.05.18
Posted by code cat
$ screen -X -S [session # you want to kill] quit


Posted by code cat
리눅스/커널2014. 2. 5. 11:44

출처:http://chaoxifer-univ.blogspot.kr/2010/10/devtty-devconsole.html


/dev/tty 와 /dev/console의 차이점


There is a subtle difference between the console and the terminal. In a windowed environment, a tty terminal is associated with each shell session; in other words, each command line window such as an xterm is a separate terminal. Redirection to /dev/tty sends output to the active window. The console, on the other hand, is the screen. It is the monitor in general. Most windowing programs provide a special switch to the shell windows that will link /dev/console to the window instead of writing output directly on the screen. In any event, output can be redirected to these devices quite easily.



출처:http://unix.stackexchange.com/questions/60641/linux-difference-between-dev-console-dev-tty-and-dev-tty0


From the documentation:

/dev/tty        Current TTY device
/dev/console    System console
/dev/tty0       Current virtual console

In the good old days /dev/console was System Administrator console. And TTYs were users' serial devices attached to a server. Now /dev/console and /dev/tty0 represent current display and usually are the same. You can override it for example by adding console=ttyS0 to grub.conf. After that your /dev/tty0 is a monitor and /dev/console is /dev/ttyS0.

An exercise to show the difference between /dev/tty and /dev/tty0:

Switch to the 2nd console by pressing Ctrl+Alt+F2. Login as root. Type sleep 5; echo tty0 > /dev/tty0. Press Enter and switch to the 3rd console by pressing Alt+F3. Now switch back to the 2nd console by pressing Alt+F2. Type sleep 5; echo tty > /dev/tty, press Enter and switch to the 3rd console.

You can see that tty is the console where process starts, and tty0 is a always current console.




  • /dev/console is a virtual set of devices which can be set as a parameter at boot time. It might be redirected to a serial device or a virtual console and by default points to /dev/tty0. When multiple console= options are passed to the kernel, the console output will go to more than one device.

  • /dev/tty0 is the current virtual console

  • /dev/tty[1-x] is one of the virtual consoles you switch to with control-alt-F1 and so on.

  • /dev/tty is the console used by the process querying it. Unlike the other devices, you do not need root privileges to write to it. Note also that processes like the ones launched by cron and similar batch processes have no usable /dev/tty, as they aren't associated with any. These processes have a ? in the TTY column of ps -ef output.


'리눅스 > 커널' 카테고리의 다른 글

Machine 이름 알아내기  (0) 2014.04.03
early_param에 대해  (0) 2014.03.31
FrameBuffer size 구하기  (0) 2013.12.11
[커널] FB 문서  (0) 2013.12.09
[안드로이드][커널]Unknown symbol _GLOBAL_OFFSET_TABLE_  (0) 2013.08.09
Posted by code cat

push 된 tag를 지워야 할 때가 있는데...

다음과 같이 하면 된다.


repo forall –c git tag –d TAG_NAME

repo forall –c git push --tags


Posted by code cat

reap (third-person singular simple present reaps, present participle reaping, simple past and past participle reaped or reapt)

  1. To cut with a sickle, scythe, or reaping machine, as grain; to gather, as a harvest, by cutting.
  2. To gather; to obtain; to receive as a reward or harvest, or as the fruit of labor or of works, in a good or a bad sense.
    to reap a benefit from exertions
  3. (computer science) To terminate a child process that has previously exited, thereby removing it from the process table.
    Until a child process is reaped, it may be listed in the process table as a zombie or defunct process.
  4. (obsolete) To deprive of the beard; to shave.
    (Can we find and add a quotation of Shakespeare to this entry?)


'소프트웨어 엔지니어링' 카테고리의 다른 글

[용어] Payload란?  (0) 2014.07.18
아파치 라이센스 2.0 사용법  (0) 2012.04.12
루틴: 루틴이름, 루틴길이,  (0) 2011.11.09
루틴: 설계  (0) 2011.11.09
Posted by code cat


출처: http://stuff.mit.edu/afs/athena/astaff/project/opssrc/cups/autoconf-2.65/build-aux/git-version-gen


Git은 알다시피, hash 값을 기반으로 형상 관리를 한다.  따라서 svn처럼 revision number에 따른 가시적인 버전 차이점을 사람이 인식하기 힘들다.

tagging이라는 훌륭한 방법이 있지만, 각 tagging마다의 차이점라던가, 어느 tagging이 우선인지(직접 사람이 tagging에 적어주지 않으면 힘들다) 등에 대해서 알 방법이 명확하지 않다.

따라서 git에서도 개발 시에, 일종의 revision numbering이 필요 할 때가 있다.  

우선 간단하게 commit 카운트로 revision numbering을 하기로 했는데, 시간이 날 때 하기 코드를 참조해서 좀 더 포괄적인 numbering 관리 방법을 만들어야 겠다.


Posted by code cat

 

454// Evaluate the expressions in argv, returning an array of char*
455// results.  If any evaluate to NULL, free the rest and return NULL.
456// The caller is responsible for freeing the returned array and the
457// strings it contains.
458char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
459    char** args = (char**)malloc(argc * sizeof(char*));
460    int i = 0;
461    for (i = 0; i < argc; ++i) {
462        args[i] = Evaluate(state, argv[i]);
463        if (args[i] == NULL) {
464            int j;
465            for (j = 0; j < i; ++j) {
466                free(args[j]);
467            }
468            free(args);
469            return NULL;
470        }
471    }
472    return args;
473}
argv의 entry들을 하나씩 Evaluate으로 패스. 

 

패스된 argv=expr을 받아서

35char* Evaluate(State* state, Expr* expr) {
36    Value* v = expr->fn(expr->name, state, expr->argc, expr->argv);
37    if (v == NULL) return NULL;
38    if (v->type != VAL_STRING) {
39        ErrorAbort(state, "expecting string, got value type %d", v->type);
40        FreeValue(v);
41        return NULL;
42    }
43    char* result = v->data;
44    free(v);
45    return result;
46}


Value *v에 expr->fn(expr->name, state, expr->argc, expr->argv) 를 assign시킴.

Value은 다음과 같은 구조체.

51typedef struct {
52    int type;
53    ssize_t size;
54    char* data;
55} Value;

 

expr은 Expr 구조체이며,

60struct Expr {
61    Function fn;
62    char* name;
63    int argc;
64    Expr** argv;
65    int start, end;

 

expr->fn은 Function 타입, Function은

57typedef Value* (*Function)(const char* name, State* state,
58                           int argc, Expr* argv[]);

형태로 정의됨.

type인 string인지 확인하고 아닐 경우, 에러 메세지를 state에 저장하고, string일 경우, 정상 진행.

마지막에 v->data를 리턴함.

이런 값들을 모아서 ReadVarArgs는 args 배열로 리턴.

 

 

expr.h

30typedef struct Expr Expr;
31
32typedef struct {
33    // Optional pointer to app-specific data; the core of edify never
34    // uses this value.
35    void* cookie;
36
37    // The source of the original script.  Must be NULL-terminated,
38    // and in writable memory (Evaluate may make temporary changes to
39    // it but will restore it when done).
40    char* script;
41
42    // The error message (if any) returned if the evaluation aborts.
43    // Should be NULL initially, will be either NULL or a malloc'd
44    // pointer after Evaluate() returns.
45    char* errmsg;
46} State;
47
48#define VAL_STRING  1  // data will be NULL-terminated; size doesn't count null
49#define VAL_BLOB    2
50
51typedef struct {
52    int type;
53    ssize_t size;
54    char* data;
55} Value;
56
57typedef Value* (*Function)(const char* name, State* state,
58                           int argc, Expr* argv[]);
59
60struct Expr {
61    Function fn;
62    char* name;
63    int argc;
64    Expr** argv;
65    int start, end;
66};

 

Posted by code cat

출처:http://kimyow.blog.me/50116380850

이 글이 가장 인기있는 글이네요.

지금와서 다시 읽어보니, 내용이 너무 두서없는 것 같아, 좀 더 이해가 쉽도록 수정을 했습니다. signing 개념 이해에 많은 도움이 되길 바라겠습니다.

=================================================================


Platform key signing 을 하는 이유는 뭘까?


왜 굳이 Platform key 로 signing 을 해야 할까?


일반적인 apk 의 경우, (일반 개발자, 3rd party 가 개발한 APK) 자신이 만든 apk 를, data 영역에 install 할 수 있으며, 또는 rooting 한 폰의 system 영역에 설치할 수 있고, 이를 실행할 수 있다.


여기서 일반적인 apk 란, 통상적을 제공되는 sdk 에서 개발 된 apk 를 말한다.

(Vendor가 아닌, 일반적인 모든 개발자가 Eclipse 등 SDK를 사용하여 개발한 Application)


Full image build 과정에서 생성되는 System image(Framework.jar)를 사용하면, 소위말하는 Internal or Hidden API 를 사용하여 build 할 수 있다.


SDK 로 제공되는 android.jar 에는 포함되지 않는 API(method) 들이 많다. 

이는 Android가 일반 개발자에게는 open 하지 않는 기능들이라고 봐도 좋다.


오직 Device 를 만들어서 파는 Vendor(삼성/LG)들만이 사용할 수 있다.


Settings.apk 의 경우,


타 모델의 apk 또는 source 를 구한다 한 들, 쉽게 자신의 phone 에 설치 & 실행이 안 될 것이다.

(Setting 만이 가지고 있는 특정 기능을 포기한 후 build 한다면, 가능하다.)


이미 당신이 가지고 있는 폰은 Vendor 가 User mode 로 build 한, 특정 key 로 signing 된 image 를 사용하기 때문이다.

( Debug or Engineer 모드로 build 된 image 가 탑재된 상태로 시장에 출시되지 않겠죠? )


User mode build 시, Vendor 는 android 에서 제공되는 known key (보통, \build\target\product\security\ 안에 있다.) 로 signing 하지 않으며, 각자의 unique 한 key 를 만들어서 signing 한다. 개발 편의를 위해서 default key 로 signing 하기도 하는데, 이는 eclipse 가 build 시 signing 하는 key 와 동일하다.


즉, Vendor 입장에서는 개발 단계와 양산 단계의 signing key 가 다른 것이다.


System 권한이 필요한 Setting 의 경우, Platform key 로 signing 후 설치된다. System과 동일한 uid 를 가져야 동일한 권한으로 data/code 사용이 가능하며 이를 위해서는 system 과 동일한 platform key 로 signing 되어야 한다.


하지만, 이미 당신이 가지고 있는 device(phone) 의 platform key 를 가지고 있지 않은 이상, 아무리 source build 를 성공해도 만들어진 Settings.apk 를 설치하기란 불가능하다.

(설치하려고 하면, INSTALL_FAILED_SHARED_USER_INCOMPATIBLE error 가 뜰 것이다.)


물론, 위에서 언급했듯이 Setting 만의 특정 기능을 뺀다면 가능하다.


Setting 만의 특정 기능이란, 타 application 을 memory 상에서 깨끗하게 kill 할 수 있는 기능이다.


이는 위에서 언급한 internal api 를 사용해야 하므로, 3rd party application 에선 사용이 불가능하며, system 권한/자격이 필요한 기능이다.


System 권한, 자격을 포기한다면, 굳이 platform key 로 signing 할 필요 없으며, 일반적인 application 으로써, 어떤 device 든지 기 설치되어 있는 settings.apk 만 확실히 제거한 후, 당신이 빌드한 새로운 settings.apk를 재설치해서 사용이 가능하다.


이 system 자격, 권한을 포기한다는 의미가, AndroidManifest.xml 에서 속성으로 명시된,

android:sharedUserId="android.uid.system" 항목을 삭제하는 것이다.


위 의미는 system process 와 같은 uid 를 사용하므로써, system process 의 code & data 를 똑 같이 공유할 수 있는 권한을 해당 application 에게 준다는 의미이다.


따라서 위 항목을 지우고 build 한 apk 를 설치하면 아주 자~~알 설치될 것이다.


하지만,~~ Settings > Applications >Manage applications 에서 "Force stop" 버튼을 클릭 하는 순간 unexpected error, 즉 setting application 이 죽을 것이다.


System 자격이 있는 넘이 호출해야 할 함수를 자격이 없는 application이 호출했기 때문에 Permission error 가 나는 것이다.


대표적인 Internal api method 인, ActivityManager 의 forceStopPackage() 를 예로 들어보자.- Internal API이므로, 일반 개발자에게는 open 되어 있지 않은 함수다.


보통 Market에서 download 받아 설치하는 일반적인 system application의 경우(TaskManager), ActivityManager.killBackgroundProcesses() 로 application 을 kill하는데, 이는 application 우선순위가 Background 이하인 application 만 kill 하는 제약을 가지고 있다.(Visible, Foreground, Service 우선순위는 완벽하게 kill 할 수 없다.)


이에 반해 ActivityManager.forceStopPackage() 함수는 아무런 제약 사항없이 대상이 되는 application 을 메모리상에서 깨끗히 지우는 기능을 한다.


이 함수를 실행하기 위해서는 permission 이 필요한데, 

<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission>

라고 AndroidManifest.xml 에 명시해줘야 한다.


이렇게 해서 build 된 apk 를 install 한 후, 실행 하면 하기와 같은 exception 이 발생한다.


==================================================================

 

07-21 10:38:13.480: WARN/ActivityManager(1981): Permission Denial: forceStopPackage() from pid=3565, uid=10110 requires android.permission.FORCE_STOP_PACKAGES

07-21 10:38:13.503: ERROR/AndroidRuntime(3565): FATAL EXCEPTION: main

07-21 10:38:13.503: ERROR/AndroidRuntime(3565): java.lang.SecurityException: Permission Denial: forceStopPackage() from pid=3565, uid=10110 requires android.permission.FORCE_STOP_PACKAGES

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.os.Parcel.readException(Parcel.java:1260)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.os.Parcel.readException(Parcel.java:1248)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.app.ActivityManagerProxy.forceStopPackage(ActivityManagerNative.java:2564)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.app.ActivityManager.forceStopPackage(ActivityManager.java:968)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at com.lge.lmk.activities.RunningProcessActivity$4.onClick(RunningProcessActivity.java:850)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:158)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.os.Handler.dispatchMessage(Handler.java:99)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.os.Looper.loop(Looper.java:123)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at android.app.ActivityThread.main(ActivityThread.java:4668)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at java.lang.reflect.Method.invokeNative(Native Method)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at java.lang.reflect.Method.invoke(Method.java:521)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)

07-21 10:38:13.503: ERROR/AndroidRuntime(3565):     at dalvik.system.NativeStart.main(Native Method)

==================================================================

 


"android.permission.FORCE_STOP_PACKAGES" Permission 을 명시해 줬는데 왜 Permission error가 날까?


이 함수를 call 하는 application쪽에 System process 의 권한이 없기 때문이다.


system process 와 동일한 권한을 갖기위해서는?


AndroidManifest.xml 파일의 manifest attribute 에 하기와 같이 지정해 주면 된다.

android:sharedUserId="android.uid.system"


이 application process 의 uid 를 system 과 공유함으로써, system 과 동일한 권한을 갖겠다는 의미다.


참 편리하게 system 권한을 가질 수 있다고 생각할 수 있지만, 이는 어디까지 platform(system)  과 signature 가 같을 때의 경우에만 해당된다.


다시한번 언급하자면,

모든 사용자가 구입한 폰은 각 Vendor 측의 고유 key로 signing 된, User mode 로 빌드 된 image 가 탑재 되었고, 각 모델별로 고유한 platform key 로 signing 되었기 때문에, 아무리 rooting 을 했건, 뭐를 했건간에, User mode 로 빌드 된 image의 key 를 바꿀 순 없다.

(Vendor 측에 아는 사람이 있어 debug 나, engineer 모드로 빌드된 image 를 구할 수 있다면??)


전체 이미지 빌드 타임에 system 과 data 영역에 들어갈 모든 APK는, 싹 다 각각 Android.mk에 명시된 key 값으로 signing 한다.


때문에, Signature 가 Platform과 맞지 않은 Settings application 을 폰에 탑재하는 순간, 아래와 같은 logcat msg 와 함께, 해당 apk 는 launcher 에서 볼 수 없을 것이다.(PackageManager 가 package loading 실패)

====================================================================

07-21 10:56:36.046: WARN/PackageManager(1981): Package com.test.application shared user changed from <nothing> to android.uid.system; replacing with new

07-21 10:56:36.054: WARN/PackageManager(1981): Signature mismatch for shared user : SharedUserSetting{462749e8 android.uid.system/1000}

07-21 10:56:36.054: ERROR/PackageManager(1981): Package com.test.application has no signatures that match those in shared user android.uid.system; ignoring!

 

====================================================================


또는,(아래는 살짝 다른 유형의 error 다.)

====================================================================

 


08-09 09:47:06.054: ERROR/PackageManager(1973): Package com.test.application signatures do not match the previously installed version; ignoring!

08-09 09:47:06.257: INFO/IQClient(2030): submitHW03 -  status- 2 level- 74

====================================================================

 


system 쪽과 signature mis-match 가 나서 이 어플을 loading 할 수 없다는 의미이다.


해결방법은 해당 어플도 똑같이 platform signing 을 해주는 방법밖에 없다.


그래야 system 권한을 얻을 수 있다는 의미이다.


하기와 같이 platform key 를 어디선가 구해와서 signing 해주면 된다.

(당연히 아래 platform key 가 당신의 device 에 flashing 되어 있는 image 의 signed platform key 와 동일해야 한다.)


Platform key 는 어디서 구할까...??? 해당 모델의 Vendor 만이 알 수 있다.


java -jar signapk.jar platform.x509.pem platform.pk8 Unsigned.apk Signed.apk


위 명령어로 생성된 Signed.apk 를 설치해주면 System 권한으로 internal api 사용이 가능하며 원하는 모든 기능이 정상 동작 될 것이다.

Posted by code cat