커널 thread 소스 분석(어셈블리 ㅠㅠ)..
int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval, d0;
__asm__ __volatile__(
"movl %%esp,%%esi\n\t" /* 이 부분은 무엇을 하는 건가염? */
"int $0x80\n\t" /* clone() 호출인데 eax에 아무것도 안 넣는데? */
"cmpl %%esp,%%esi\n\t"
"je 1f\n\t" /*이건 1(float) "1:\t" 뛰는거져 */
"movl %4,%%eax\n\t"
"pushl %%eax\n\t" /* 함수 호출시 파라미터 넣기 */
"call *%5\n\t"
"movl %3,%0\n\t"
"int $0x80\n"
"1:\t"
/* 출력 */ :"=&a" (retval) /* %0 */ , "=&S" (d0) /* %1 */
/* 입력 */ :"0" (__NR_clone) /* %2 */ , "i" (__NR_exit) /* %3 */,
"r" (arg) /* %4 */, "r" (fn) /* %5 */,
"b" (flags | CLONE_VM) /* %6 */
/*변경된레지스터*/ : "memory");
return retval;
}
이 커널 소스가
int kernel_thread(int (*fn)(void*), void *arg, unsigned long flags)
{
pid_t p;
p = clone(0,flags | CLONE_VM);
if (p)
return p;
else {
fn(arg);
exit();
}
}
이 역할을 한다구 하는데 인라인 어셈블리땜시 이해가 잘 안되네염 ㅠㅠ
어느 정도는 이해를 했는데 자세하게는 잘 모르겠어요
위 어셈블리 코드 분석좀 부탁드립니다.
다는 모르겠구요 제가 아는대로라도 말씀드리면요__asm__ __v
다는 모르겠구요 제가 아는대로라도 말씀드리면요
__asm__ __volatile__(
"movl %%esp,%%esi\n\t"
-> 스택에는 d0이 들어있습니다.
그래서 먼저 d0을 esi 레지스터에 저장했다가
아래 인터럽트 호출 후에 스택에 있는 d0값이 변했나 확인해서 (je 1f부분)
변하지 않았으면 바로 종료합니다.
변했으면 je 다음 줄부터 실행합니다.
"int $0x80\n\t"
-> 80번 인터럽트를 호출합니다. 여기서 eax에 들어있는 값이 따라
다른 시스템 콜이 호출돼는 콜 게이트라는 거라고 들었습니다.
아마 clone을 호출하는 것 같습니다.
"cmpl %%esp,%%esi\n\t"
"je 1f\n\t"
"movl %4,%%eax\n\t"
"pushl %%eax\n\t"
"call *%5\n\t"
-> 여기서 %5는 fn을 가리킵니다. 그리고 바로 윗줄의 %4는
arg를 가르킵니다. 그래서 콜링 컨벤션에 따라
arg를 스택에 넣고 fn을 호출합니다.
"movl %3,%0\n\t"
"int $0x80\n"
-> retval에 NR_exit 값을 넣어서 콜 게이트를 호출합니다.
왜 어떤 시스템 콜을 호출하는 지는 모르겠습니다.
"1\t"
"=&a" (retval), "=&S" (d0)
"0" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
"b" (flags | CLONE_VM)
"memory");
인라인 어셈블리에 대해서는 알겠는데
커널이 어떻게 동작하는 지를 잘 모르겠네요.
도움이 잘 안됄것 같네요..쩝. oops
Re: 커널 thread 소스 분석(어셈블리 ㅠㅠ)..
여기서 exit()는 _exit()가 되어야 맞습니다. 스레드를 하나만 종료했는데 exit()를 호출하면 다른 스레드들까지 전부 죽어 버리는 현상이 발생하니까요.
그리고 int $0x80와 같은 명령은 인터럽트 게이트라고 합니다. 콜 게이트는 call 명령을 쓰는 것을 말합니다.
한국 BSD 사용자 포럼
댓글 달기