BLOG main image
카테고리 (57)
리눅스 (9)
파이썬 (7)
윈도우 (2)
스터디/세미나 후기 (29)
IT일반 (3)
소소한 일상 (5)
현실로 이루어질 몽상 (0)
32,278 Visitors up to today!
Today 6 hit, Yesterday 5 hit
daisy rss
tistory 티스토리 가입하기!
2008/02/09 19:11
 드디어 리눅스 커널 소스 분석 스터디가 끝났다. 처음 스터디를 시작하면서 목표로 했던 리눅스 부팅 과정이 완료되는 부분까지 분석을 완료하였다. 작년 2월에 시작해서 올해 2월에 끝났으니 1년이라는 오랜 기간 동안 처음에 시작했던 멤버 대부분이 같이 끝을 볼수 있어서 기뻤다. 기나긴 여정동안 포기하지 않고 마무리를 제대로 할 수 있어서 뿌듯했다. 혼자서 했으면 시작조차 할 엄두가 나지 않았을텐데, 같이 스터디 하시는 분들이 계셨기에 무사히 끝낼수 있었던것 같다. 항상 느끼는 부분이지만 같이 스터디 하시는 분들은 참으로 대단하신 분들이다.

 저번주에 회사에서 태안반도 봉사활동 가느라  한주 빠졌었는데 저번주에 스터디 참여 인원이 2분이었다고 한다. 저번주에 끝내는 목적으로 스터디를 하여서인지, 2분이서 엄청난 분량을 하셨다. 저번주 스터디에 참여 하신 형주님께서 이번에 스터디 시작에 앞서 저번주에 했던 부분을 잠깐 리뷰 해 주셨다.

 저번주 했던 부분은 start_kernel()의 radix_tree_init() ~ rest_init() 일부까지 진행을 하였다. 대부분이 관련된 자료구조 초기화 부분이고, 현재 타겟으로 하고 있는 아키텍처인 x86_64에서 안쓰이는 함수가 몇몇 있어서 진도를 빨리 나갈수 있었다고 하였다.

 이번주에는 start_kernel() -> rest_init()에서 커널 스레드로 생성하는 init() 함수와 cpu_idle() 함수를 분석하였다. rest_init() 함수는 init 커널 스레드를 생성하고 스케쥴링 한다. 이후에 다시 rest_init()로 스케쥴링 되었을때는 cpu_idle() 함수를 실행하여, idle 프로세스로 바뀌게 된다.

 커널 스레드인 init() 함수는 크게 보면 다음과 같은 작업을 한다.

  1. 멀티 프로세서의 초기화(이 시점에서 부팅 CPU를 제외한 다른 CPU가 활성화 된다.)
  2. 기타 부가 기능들의 초기화 함수 실행(커널에 포함된 디바이스 드라이버의 초기화 함수등)
  3. 표준 입출력 파일 open(표준 입력(0)/표준 출력(1)/표준 에러(2))
  4. init 프로그램의 실행
 init() 함수는 마지막에 init 프로그램을 실행하는데, 이때 실행할 init 프로그램을 전역변수 execute_command를 설정하면 사용자가 지정 가능하다. 정확하게 분석 하지는 않았지만, 부트로더에서 부팅시에 커널 파라메타로 넘겨주는듯 하다. 그리고 run_init_process()로 init 프로그램을 실행 하는데, run_init_process()는 내부적으로 kernel_execve()를 실행하여, 프로세스를 바꾸어주는 역활을 한다. 즉, 커널 스레드 init()를  "init" 프로그램으로 변경한다.

 cpu_idle() 함수는 현재 시스템에서 별다른 프로세스가 실행되지 않을때 실행되는 우선순위가 낮은 프로세스 이다.  while(1)로 묶여있어서, 무한루프를 돌면서 idle 프로세스를 실행한다. idle 프로세스 실행이 끝나면, 스케쥴러를 호출하여, 스케쥴링 되어야 할 다른 프로세스가 있으면 그 프로세스를 실행한다. idle 프로세스 수행중에 인터럽트가 발생하면, idle 프로세스가 종료된다.(do_irq() 함수에서 exit_idle() 함수를 호출하여 idle 프로세스의 수행을 끝낸다.)

 리눅스는 프로세스 생성을 복사/변경 매커니즘으로 한다. fork() 시스템 콜로 부모와 같은 복사본을 만들고, exec() 시스템콜로 자신에 맞게 변경을 해서 프로세스를 생성하게 된다. 이때, 모든 프로세스의 조상이 되는 PID(프로세스 ID) 1번인 프로세스가 init 프로세스 이다. init 프로세스 생성은 앞서 보았던 부팅 과정 마지막에 init() 함수에서 init 프로세스로 변경되는 부분에서 생성이 되었다. init 프로세스는 모든 프로세스의 조상의 역활뿐만 아니라, /etc/inittab을 참고하여 리눅스 부팅때 수행되는 프로그램들을 기술한 스크립트를 실행하는 역활도 한다.

 이제 리눅스 커널 스터디 관련 포스팅도 끝이다. 앞으로 남은 일정은 2월 한달동안 각자 맡은 부분 리뷰 자료를 만들기로 하였고, 3월동안 지금까지 했던 스터디의 리뷰를 통해, 리눅스 부팅과정 및 리눅스 커널의 구조에 대한 이해도를 높이기로 하였다.

그리고, 리뷰 자료를 체계적으로 정리하여, 지금까지 스터디 했던 내용을 좀더 많은 사람들과 공유 할 수 있도록 리눅스 부팅 프로세스 관련 기사를 월간 마이크로소프트웨어에 기재 하기로 하였다. 확실한 것은 아니고, 일단 자료의 퀄리티를 높여서  마소 측에 컨택을 해보기로 하였다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/66 관련글 쓰기
Name
Password
Homepage
Secret
2008/01/24 13:23

 아직 살아온 날보다 살아갈 날이 더 많이 남았고, 그렇게 오랜 시간을 살아온건 아니지만, 지금까지 살아오면서 느낀 점이 하나 있다. 무슨 일을 하던간에 그것을 제대로 하려고 하면, '시작'과 '끝'이 가장 중요 하다는 것이다. 일단 '시작'을 해야 되든 안되는 결과가 나올것이고, 성공적인 결과를 도출하려면 '끝' 마무리를 신경을 써야한다.  

 각각에 필요한 조건들 중에 개인적으로 중요시 여기는 것들이 몇가지 있다. '시작' 하는데 필요한것은 '열정'과 '배짱', '끝'을 제대로 마무리하는데 필요한것은 '프로의식'과 '근성'이다. 주위를 보면 무조건 어렵다고 시도(시작)조차 하지 않는 사람들은 세월이 흐르더라도 발전하지 못하고 항상 제자리 걸음을 하면서 현실에 안주하며 살아간다. 그리고 사소한 것이라고 그것을 건성으로 하는 사람들은 결과는 나오겠지만, 그것이 제대로 된 것이 하나도 없을것이다. 이런 조건들을 모두 갖춘 사람들은 무슨 일을 하더라도, 성공을 했거나, 할 것이다.

 스터디 후기에 갑자기 왠 인생타령이냐 하겠지만, 요즘들어 커널 스터디가 끝나는 시점이 되다보니 조금씩 너프해지는게 아쉬워서 그런다. 시작할때의 열정이 지금은 많이 사라져서, 많이 안타깝다. 물론 이제 한걸음만 더 나아가면 스터디가 끝나기 때문에, 흐지부지 된다던지 하는 일은 없을 것이다. 마무리를 잘해서 제대로 했던 스터디로 기억에 남도록 얼마남지않은 기간동안 다시 열정을 불태워야 겠다.

 이날은 개인 사정상 참여인원이 적고, 늦게 시작하고 일찍 마쳐서 진도를 얼마 나가지는 못했다. 다행히도 장소를 제공해주시는 상민님께서 나오셨고, 스터디 진행하는 효율적인 방법을 찾아서 만족스러운 스터디를 하였다.
 이날 진행했던 부분은 start_kernel() -> vfs_caches_init() -> files_init()와 mnt_init()를 진행하였다.

 file_init()는 VFS(Virtual File System)에서 열린 파일을 관리하는  file 객체를 초기화 해주는 함수이다. 처음에 현재 여유공간에서 할당 할 수 있는 inode 또는 dcache의 수의 10%를 현재 시스템에서 열수 있는 파일 갯수로 초기화 한다.(max_files) 그리고 files_defer_init() 함수를 호출한다.
 files_defer_init() 함수는 현재 시스템의 CPU만큼 루프를 돌면서 fdtable_defer_list_init()를 호출한다. fdtable_defer_list_init() 함수는 현재 CPU의 fdtable_defer_list 변수 값을 가져와서 워크 큐를 free_fdtable_work()로 초기화 한다. 이렇게 하면 free_fdtable_work()가 워크큐를 실행하는 시점에 수행하게 된다. struct fdtable이 있는데 struct fdtable_defer를 따로 둔 이유는 fdtable은 프로세스 당 한개씩 할당되는 자료구조이다. 그런데, fdtable_defer는 CPU당 한개씩 할당된다. fdtable_defer에 워크큐를 둠으로써, fdtable에 워크큐를 넣는것을 피할 수 있다.
 마지막으로 file_init()는 cpu 카운터의 nr_files를 0으로 초기화 하고 수행을 끝낸다.

 mnt_init()는 파일 시스템을 초기화 하는 함수 이다. 자료구조 관련 동작은 vfsmount 슬랩을 생성하고, mount_hashtable을 위해서 1 page를 할당한다. 그리고 sysfs_init()와 init_rootfs(), init_mount_tree()를 호출하여 다음과 같은 동작을 한다.

  1. sysfs 초기화(/sys 에 있는 파일 시스템)
  2. 루트 파일 시스템 초기화
  3. 파일 시스템의 작업 경로 설정
  4. 파일 시스템의 root 경로 설정

 이번주는 회사에서 태안반도 봉사활동 참여하느라 스터디에 참여하지 못한다. 1월 중으로 분석을 끝내기로 하여서, 진도를 상당히 많이 나갈텐데 참석하지 못하니 아쉽다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/65 관련글 쓰기
Name
Password
Homepage
Secret
2008/01/09 23:11
 스터디 후기는 당일날 올려야 알찬 내용의 포스팅이 되는데, 귀차니즘으로 3일이나 지난 오늘에야 후기를 올리게 되었다. 요즘 새로 입사를 하면서 업무 파악 및 회사 분위기 적응에 많은 신경을 쏟아서 그런것 같다.

 저번주 스터디는 예전에 하다가 말았던 '슬랩 할당자' 초기화 루틴의 분석을 끝냈다. start_kernel() 함수에서 kmem_cache_init() 부분이다. 3주째 이 부분을 하고있는데, 3번째 보게되니 많이 명확해졌다. 이 함수는 앞서 포스팅 했던 것처럼 슬랩 할당자를 초기화 하는 함수이다. 주석으로 슬랩 할당자 초기화 단계가 달려있어서, 이 내용대로 루틴이 작성되어 있는데, 해당 내용은 다음 링크를 참고하길 바란다.


 이날 했던 내용은 저번주 했던 부분 리뷰하고, 할당되는 슬랩 관련 자료구조에 대해 그림을 그려 보았다. 그리고 '슬랩 컬러링'이라는 주제를 가지고, 이부분에 대해 토론을 하여 어느정도 이해를 할수 있었다. 슬랩 컬리링은 캐쉬라인에 최적화하기 위한 기법이다. 이는 슬랩 디스크립터(struct kmem_cache)에 colour, colour_off, colour_next 멤버를 가지고 제어를 하는데, 물리적인 메모리 1 page의 앞부분에 일정 공간을 비워두는 방식으로 캐쉬라인에 최적화를 한다. 이 비어있는 공간을 colour과 colour_off로 나타낸다.(우리는 'left over 공간'라고 지칭하였다.). CPU의 캐쉬의 크기를 colour_off에 넣고 left over 공간을 colour_off를 나누면 color 값이 나온다. 반대로 colour*colour_off를 하면 left over 공간의 크기를 알 수 있다. 아직까지 슬랩 컬러링에 대한 내용은 캐쉬라인 동작을 정확하게 조사하지 않아서 100% 이해는 되지 않았다. 나중에 시간이 나면 캐쉬라인 동작에 대해 조사해서 서로 연관해서 다시 한번 보아야 겠다.

 그리고 슬랩 초기화의 나머지 부분은 크게 어려운 부분이 없었다. 리눅스 커널이 부팅때만 사용하는 데이타인 __init data에 있는 내용을 메모리 할당을 해서 그 부분으로 복사해주는 루틴이었다. 부팅이 끝나고 해당 데이타가 해제 되어 버리면 안되는 것이니...

 이제 start_kernel() 부분도 거의 끝나가고, 앞으로 어려운 내용이 거의 없기 때문에, 1월 중으로 리눅스 커널 초기화 루틴 분석을 끝내기로 하였다. 그리고 2월에 지금까지 했던 내용을 한번 리뷰를 하고, 이어서 하게 될 프로젝트(혹은 책 집필)에 대해 논의하기로 하였다.

이번주는 스터디 진도가 상당히 많이 나갈텐데, 안타깝게도 나는 다음/네이버에서 개최하는 메쉬업 캠프에 참가하는 까닭에 스터디 참여를 하지 못한다. 재밌는 점은 메쉬업 캠프가 리눅스 커널 스터디 장소와 같은 장소에서 한다는 것이다.
 
이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/64 관련글 쓰기
Name
Password
Homepage
Secret
2008/01/03 06:05
 파이썬 스터디도 이제 끝났다. 3달 가량 계획하고 했었는데, 생각보다 한달 반 정도 오버 되었다 중간에 휴일이나 개인적 사정등으로 몇번 빠전것을 제외하면 4달만에 끝난것 같다. 생각보다 오래 걸렸지만, 기간보다는 끝까지 잘 마무리 했다는게 뿌듯하다.

지금까지 했던 내용을 정리하면, 첫달 한달동안 파이썬 문법을 끝냈고 나머지 세달동안 파이썬으로 작성된 MSN 메신저 클론인 emesene를 분석하였다. 파이썬 스터디를 그냥 마무리하면 아쉬워서, 정리하는 차원에서 의미있는 다음과 같은 아웃풋을 만들어 보았다. 둘다 명현군이 대부분의 작업을 하였고, 나는 서포트하는 형식으로 하였다. (필 받은 사람은 말리기 힘들다;;)

  • emesene 한글판 언어 패키지
  • emesene plugin
 이외에도 분석한 내용을 주석으로 달아놓은 소스 파일과 전체 구조를 분석 한 다이어그램등이 있는데, 이것들은 분석에 대한 자료들이라 일반 유저에게는 필요 없을듯 하다.


1. emesene 한글판 언어팩 설치

MSN 메신저 클론 메신저인 emesene는 다음 링크에서 다운로드 받을 수 있다.

emesene 다운로드

tar로 다운 받은 파일 압축을 풀자.

사용자 삽입 이미지

압축을 푼 emesene 디렉토리의 하위 디렉토리 po  밑에 ko.tar.gz를 복사해서 압축을 푼다.


사용자 삽입 이미지

emesene 한글판 설치 끝!

사용자 삽입 이미지

< 한글 언어 팩 설치 전 >

사용자 삽입 이미지

< 한글 언어 팩 설치 후 >

2. emesene plugin 설치

 파이썬 스터디 아웃풋의 일환으로 plugin을 만들어 보았다. 간단한 숫자 야구 게임을 메신저를 사용하면서 할 수 있는 플러그인 이다. emesene plugin 설치는 간단하다. emesene가 설치된 디렉토리의 plugins_base 디렉토리 아래에 플러그인 파일을 넣어주면 끝이다.


 위 플러그인을 emesene/plugins_base 디렉토리에 넣어주면 plugin이 설치 된다.
사용자 삽입 이미지
< BaseBall Plugin >

사용방법은 대화창에서 /baseball 을 입력하면 된다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/63 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/31 07:51
 오늘은 iamroot.org 전체 단합 송년회를 하였다. iamroot.org 전체적인 관점에서 보면 가상화 프로그램의 하나인 XEN 분석 스터디의 첫 모임을 가졌고, 가상화 분야의 전문가 이신 최영호님을 모시고 XEN 세미나을 하였다. 세미나 내용을 간략하게 요약해 보았다.

XEN 세미나

1부 가상화 개요
  • 가상화 개요
  • 가상화를 사용하는 이유
  • 가상화 기술의 역사
  • 가상화 분류
    • 플랫폼 가상화
    • 리소스 가상화
  • 플랫폼 가상화 분류
    • 시스템 가상화
      • Type1, Type2
      • Full Virtualization, Para Virtualization
      • H/W assistant
    • 프로세스 가상화
2부 XEN
  • XEN 아키텍처
    • domein 0(Control OS), domein U(Guest OS)
  • Hypercall/Event
  • CPU 가상화
    • domein 스케쥴링 알고리즘
      • BVT
      • SEDF
      • Credit
  • Memory 가상화
    • MMU 가상화
      • Direct Mode
      • Shared Mode
    • 공유 메모리
    • Scatter-gather 문제
  • I/O 가상화
    • 가상 Device Driver
      • Frontend Driver
      • Backend Driver
    • Frontend/Backend Driver의 문제점
    • Driver Domain(Isolated Driver)
    • H/W assistant을 사용한 해결방안
  • XEN Tools
    • XenTracBuffer
    • XenOprofile
    • XenDebug
 이렇게 유익한 내용의 세미나를 바쁘신 와중에 시간을 내어 해주신 최영호님께 감사할 따름이다. XEN 세미나가 끝나고, 송년회를 하러 고기집으로 갔다. 예전부터 그랬던 것처럼 1차는 팀별로 모여서 한잔하는 자리를 가지고, 2차/3차부터 남은 분들끼리 섞여서 다른팀 분들과도 얘기를 나눌수 있는 기회를 가졌다. 처음 리눅스 커널 스터디 회식할때 부터 그랬지만 IT 관련 얘기로 밤샐수 있는 술자리는 iamroot.org에서 처음이었다. 그러면서도 부자유스럽지 않고 자연스럽고 편하다는게 신기했다. 세미나와 송년회 모두 의미있는 시간이었다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/62 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/27 06:25
 오늘로써 파이썬 기반 메신저 'emesene' 분석은 끝났다. 평일날 진행하는 스터디라서 참석율도 저조하고, 끝까지 할수 있을지 의구심이 많이 들었는데 열정과 근성으로 여기까지 온것 같다.

 화요일날 진행하는 스터디인데, 명현군의 요청으로 수요일날 진행하게 되었다. 수요일날은 저녁에 AMD64 아키텍처 스터디를 하기 때문에 오후 일찍 모여서 스터디를 진행하였다. 이후에 AMD 스터디는 캔슬되어서 저녁 늦게까지 파이썬 스터디를 할 수 있었다.

 오늘 주로 했던 부분은 emesene의 실행 흐름을 분석하는 부분은 끝났기 때문에, 프로그램의 전체구조를 보는데 중점을 두었다. 명현군이 개인적으로 시간을 투자해서 emesene 전체 구조를 다이어그램으로 그려왔다. 그것을 보면서 소스를 확인하고, 모호한 부분이 있으면 바로 수정하면서 확인하였다. 중간에 잠시 gtk 자체 슬롯함수 때문에 잠시 막혔었다.

 gtk나 qt나 어떤 위젯(객체)에서 시그널을 발생시키면, 그시점에 동작하는 함수를 슬롯 함수라고 한다. 일반적으로 connect()를 써서 시그널과 슬롯 함수를 연결 시켜줘야 한다. 그런데, connect()를 하지 않았는데 동작하는 gtk 내부 슬롯 함수가 있었다. do_(시그널명) 으로 지정된 함수는 do_(시그널명) 함수가 속한 class내에서 시그널이 발생했을때 connect()를 하지 않아도 동작할 수 있다. connect() 하는 부분이 없어서 이것 찾는다고 고생하였다.

 다음주 스터디는 마지막 파이썬 스터디이다. 그냥 스터디를 끝내면 아쉽기 때문에  무엇인가 아웃풋을 남기기로 하였다. 총 네가지 아웃풋을 남기기로 하였다.

1. emesene 분석하면서 주석이 달려있는 소스
2. emesene 분석 문서
3. emesene 한글 언어 패키지
4. emesene plugin

 1번은 이미 끝났고, 2번은 명현군이 그려놓은 다이어그램이 있어서, 그것을 조금 다듬기만 하면 된다. 3번은 내가 틈틈히 작업하기로 하였고, 4번은 emesene plugin 구조를 한번 봐오고, 어떤것을 만들것인지 생각해 오기로 하였다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/61 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/16 00:28
 정말 추운 날씨였다. 개인적인 체감으로는 올해 들어 가장 추운 날이 아니었나 싶다. 오늘 스터디는 스터디 장소 카펫 청소 때문에 평소보다 조금 지체되었다. 그래도 페이스를 끌어올려서 늦게 시작한만큼 늦게 끝났다. 결국 평소만큼 스터디를 한것같다. 진도는 얼마 나가지 못했지만...

 오늘 보았던 부분은 start_kernel() 함수에서 cpuset_init_early()kmem_cache_init() 일부를 보았다. 최근 스터디 경향이 큰 흐름만 보는 방식으로 바뀌었는데, 오늘은 조금 디테일하게 보았다. 그래서 진도는 얼마 나가지 못했다.

 cpuset_init_early() 함수는 CONFIG_CPUSETS가 정의되어 있어야 동작을 한다. cpuset_init_early() 함수 뿐만 아니라, cpuset 관련된 함수와 자료구조 모두가 그렇다. cpuset 이라는 개념은 멀티코어 환경에서 task가 동작하는 cpu의 친화력을 지정해주는 개념이다. 예를들면, 'CPU0', 'CPU1', 'CPU2' 처럼 cpu가 3개인 멀티코어 환경에서 'TASK1'의 cpuset을 'CPU1'로 설정해주면 'TASK1'은 가능하면 'CPU1'에서 실행되게 한다. '친화력', '가능하면' 이라는 단어에서 나타내듯이 100% 해당 CPU에서 동작하는것을 보장해주지는 않는다. cpuset은 CPU뿐만 아니라, NUMA 환경에서 메모리의 친화력도 지정할 수 있다. 이 기능은 주로 멀티코어를 가진 대형 시스템에서 로드 밸런싱의 용도로 쓰일듯 하다.

 kmem_cache_init() 함수는 리눅스 커널의 메모리 관리 매커니즘의 하나인 '슬랩 할당자' 관련 초기화를 수행하는 루틴이다. 다음과 같은 단계로 슬랩 할당자를 초기화 한다.

1. cache_cache 캐쉬를 초기화 한다.
2. 첫번째 kmalloc 캐쉬를 만든다.
3. kmalloc 캐쉬 나머지를 만든다.
4. cache_cache를 위한 __init data 배열들과 kmalloc으로 할당되는 배열들인 첫번째 kmalloc 캐쉬를 바꾼다.
5. cache_cache를 위한 kmem_list3의 __init data와 다른 캐시들의 kamlloc으로 할당된 메모리를 바꾼다.
6. 최종 크기들로 kmalloc 캐시들의 head arrays의 크기를 조절한다.

저 단계중에 현재 4번까지 분석을 완료했다. 4번 단계까지 루틴에서 'cat /proc/slabinfo'을 쳤을때 나오는 kmem_cache, size-xx, size-xx(DMA) 이름을 가진 슬랩들이 만들어진다. 슬랩을 만들때는 kmem_cache_create()라는 함수를 이용한다.

 오늘 분석했던 루틴중에 신기한 기법이 있었다. 슬랩의 cache 이름을 담고있는 구조체가 있는데 다음과 같이 정의되어 있다.

static struct cache_names __initdata cache_names[] = {
#define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
#include <linux/kmalloc_sizes.h>
{NULL,}
#undef CACHE
};

cache_names[]를 초기화 할 때, CACHE() define 함수를 정의했다가, 없애버린다. 그리고, 중간에 <linux/kmalloc_sizes.h>를 include 하였다. kmalloc_sizes.h를 열어보면 다음과 같이 되어있다.

 1 #if (PAGE_SIZE == 4096)
 2   CACHE(32)
 3 #endif
 4   CACHE(64)
 5 #if L1_CACHE_BYTES < 64
 6   CACHE(96)
 7 #endif
 8   CACHE(128)
 9 #if L1_CACHE_BYTES < 128
10   CACHE(192)
11 #endif
12   CACHE(256)
13   CACHE(512)
14   CACHE(1024)
15   CACHE(2048)
16   CACHE(4096)
17   CACHE(8192)
18   CACHE(16384)
19   CACHE(32768)
20   CACHE(65536)
21   CACHE(131072)
22 #if (NR_CPUS > 512) || (MAX_NUMNODES > 256) || !defined(CONFIG_MMU)
23   CACHE(262144)
...

결국 kmalloc_sizes.h 에서 CACHE() define 함수를 사용해서 cache_names[]을 초기화 한다. CACHE(x)에서 x값이 32,64,96,128... 이렇게 증가하므로, cache_names[0].name = "size-32", cache_names[1].name = "size-64"... 이렇게 초기화가 된다. 이것들은 'cat /proc/slabinfo' 에서 나오는 슬랩의 name들과 동일하다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/60 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/14 15:32
1. 커널의 Makefile로 점프

 리눅스 모듈의 컴파일 과정을 분석하기 위해 말책(리눅스 디바이스 드라이버)의 예제 scull의 컴파일 과정을 추적하겠다. scull을 컴파일 하려면 해당 디렉토리에서 'make' 를 하면 된다. 그럼 scull 이제부터 scull의 make이 어떻게 동작하는지 분석 해보겠다.
 scull 및 기타 예제 소스는 다음 링크에서 다운로드 받을 수 있다.


 scull 디렉토리의 Makefile을 열어보면 다음과 같은 라인을 볼수 있다.

example/scull/Makefile
 modules:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
 
 이 부분이 실제 scull을 컴파일하는 부분과 관련 있는 부분이다. 분석을 하면 -C 옵션에 의해 모듈 라이브러리 디렉토리(/lib/modules/(현재 커널 버전)/build)에서 make를 하라는 의미다.
 이때, 매개변수 M에 현재 디렉토리를 넣어준다. /lib/modules/(현재 커널 버전)/build는 현재 커널 버전의 리눅스 커널 소스 파일이 있는 디렉토리를 심볼릭 링크하고 있다. 커널의 Makefile은 커널을 컴파일 할 때만 쓰는게 아니라 지금 처럼 모듈을 생성할때에도 사용한다. 그외 커널 소스의 ctag를 만들수도 있다. 이처럼 커널의 Makefile은 여러가지 용도로 사용 가능하게 만들어 두었다.
 두번째 매개변수로 LDDINC에 (현재 scull 디렉토리)/../include 를 넣어주었다. 그리고 modules 심볼을 넣어주었다. LDDINC는 scull Makefile 내부에 CFLAGS 값에 추가 시켜주기 위해 사용되었다.

example/scull/Makefile
CFLAGS += -I$(LDDINC)

-I 옵션은 gcc로 컴파일을 할때, include 경로를 추가 시켜주는 옵션이다.

전체적으로 보면 다음과 같다.

make <make의 매개변수들> modules

 현재 필자가 쓰고있는 시스템에서 커널 버전이 2.6.23.8 이므로 /usr/src/linux-2.6.23.8/Makefie을 실행 한다. 커널 소스 디렉토리의 Makefile로 가보자.


2. KBUILD_EXTMOD 변수 정의

 Makefile은 해당  target을 실행하고, target에 해당되는 dependency 들을 체크하고,  dependency를 수행해야 되는 경우에만 dependency를 수행하기 때문에,  target에서 부터 dependency들로 역순으로 올라가면서 분석 하는 방법도 있다. 하지만 여기서는 편의상  수행되는 순서대로 분석을 하도록 하겠다.

 관련된 부분은 1184 라인 ~ 1276 라인까지 이다. 커널 버전마다 다를 수 있으므로, 'KBUILD_EXTMOD' 심볼로 검색 해서 '# KBUILD_EXTMOD' 주석이 달려있는 else와 endif문을 찾으면 된다.

 커널 Makefile에서 target이 'modules:'를 찾아보면 978 line과 1223 line 두가지가 있다. 562 line, 1184 line, 1276 line 이렇게 ifeq() ~ else ~ endif로 묶여져 있다. 조건은 KBUILD_EXTMOD가 정의되었는지 여부이다. 지금은 다음과 같이 KBUILD_EXTMOD가 정의 되어 있으므로 1223 line의 modules: 가 적용이 된다. 978 line의 modules는 커널 소스에서 'make modules' 쳤을때 실행되는 부분이다.

/usr/src/linux-2.6.23.8/Makefile
  72 ifdef M
  73   ifeq ("$(origin M)", "command line")
  74     KBUILD_EXTMOD := $(M)
  75   endif
  76 endif

 M이 정의 되어있으면 M이 커맨드 라인에서 정의 된 변수인지 확인한다. 조건을 만족하면 KBUILD_EXTMOD에 M의 값을 넣어 준다. 
커널의 Makefile을 실행할때 매개 변수 M에 값을 넣어 줬으므로, 지금에서는 scull이 있는 디렉토리 절대 경로가 KBUILD_EXTMOD 변수에 들어 간다.
73 line의 origin 함수는 make 파일 내에서 사용되는 변수가 어디에서 정의 되었는지 판별할때 사용한다.


3. '.tmp_versions ' 디렉토리 생성

/usr/src/linux-2.6.23.8/Makefile
1204 KBUILD_MODULES := 1
1205 PHONY += crmodverdir
1206 crmodverdir:
1207   $(Q)mkdir -p $(MODVERDIR)
1208   $(Q)rm -f $(MODVERDIR)/*

 KBUILD_MODULES에 1을 넣고, PHONY에 crmodverdir을 추가 시켜 준다.
 PHONY는 해당 심볼이 실제 파일이 아니고, make에서 쓰이는 가상의 이름이라는 것을 나타낸다. 예를 들면 make에서 흔히 쓰이는 all이나 clean같은 심볼을 말한다. make을 수행 할 때 이런 이름과 같은 이름의 파일이 있으면 오 동작을 일으킬수 있으므로, PHONY로 지정하여 실제 파일과 상관 없다는것을 알려 준다.
 그리고 make는 현재 디렉토리에 MODVERDIR 변수에 들어있는 디렉토리를 만든다. mkdir에 -p 옵션을 줘서, 이미 디렉토리가 있더라도 에러로 판별하지 않는다.
 MODVERDIR은 다음과 같이 정의 되어 있다.
 
/usr/src/linux-2.6.23.8/Makefile
 336 export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions

 MODVERDIR은 KBUILD_EXTMOD 값이 있으면, KBUILD_EXTMOD의 값 중에 공백으로 구분한 첫번째 단어를 넣는다. $(if A, B)에서 A는 조건을 말하고, B는 A가 참이면 B값이 들어간다. 결국 KBUILD_EXTMOD가 정의 되어 있으므로

export MODVERDIR := $(firstword $(KBUILD_EXTMOD))/.tmp_versions

으로 변환 된다. 만약, KBUILD_EXTMOD가 정의 되어 있지 않으면

export MODVERDIR := .tmp_versions

가 된다. export는 하위 make 파일에서 이 변수를 사용 할 수 있게, 외부로 공개하는 것이다.

결국, 현재 scull 모듈이 있는 디렉토리에 '.tmp_versions'라는 숨겨진 디렉토리를 만든다. 현재 scull 소스가 있는 디렉토리에서 'ls -al'로 확인 해 보면, .tmp_versions 라는 숨겨진 디렉토리가 생성되어 있을것이다.


4. Module.symvers 파일 체크

/usr/src/linux-2.6.23.8/Makefile
1210 PHONY += $(objtree)/Module.symvers
1211 $(objtree)/Module.symvers:
1212   @test -e $(objtree)/Module.symvers || ( \
1213   echo; \
1214   echo "  WARNING: Symbol version dump $(objtree)/Module.symvers"; \
1215   echo "           is missing; modules will have no dependencies and modversions."; \
1216   echo )

 objtree는 현재 커널 Makefile이 있는 경로이다
(146 line). /usr/src/linux-2.6.23.8/Module.symvers 파일이 있는지 확인하고, 없으면 경고 메세지를 출력한다.


5. scripts/Makefile.build 으로 점프

/usr/src/linux-2.6.23.8/Makefile
1218 module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
1219 PHONY += $(module-dirs) modules
1220 $(module-dirs): crmodverdir $(objtree)/Module.symvers
1221   $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)

module-dirs에 KBUILD_EXTMOD 변수에 있는 문자열에 "_module_"을 앞에 붙여서 넣어준다. addprefix는 다음과 같은 형태를 가진다.
$(addprefix PREFIX,NAMES...)
NAMES에 들어오는 문자열들에다가 PREFIX 문자열을 앞에다가 붙여준다. 지금은 KBUILD_EXTMOD가 scull이 있는 디렉토리 이므로 scull이 있는 디렉토리를 /usr/src/example/scull이라고 가정하면 다음과 같은 값이 module-dirs에 들어가게 된다.

module-dirs := _module_/usr/src/example/scull

 그러면 ' $(module-dirs): crmodverdir $(objtree)/Module.symvers'도 다음과 같이 치환된다.

_module_/usr/src/example/scull: crmodverdir /usr/src/linux-2.6.23.8/Module.symvers

 결국 module-dirs는 crmodverdir와 Module.symvers을 의존성을 가진다. crmodverdir는 앞서 언급한 '.tmp_versions' 디렉토리를 생성하는 루틴이다.
1221 line의 patsubst는 다음과 같은 형태를 가진다.
$(patsubst PATTERN,REPLACEMENT,TEXT)

 TEXT에서 PATTERN에 해당되는 라인을 찾아서, REPLACEMENT로 바꾸어 주라는 의미이다. 현재는 TEXT가 $@, 즉 '
_module_/usr/src/example/scull' 이므로(변수 module_dirs의 값), 앞의 '_module_'을 없애 버리는 역활을 한다.

 1221 line의 build는 /usr/src/linux-2.6.23.8/scripts/Kbuild.include에 다음과 같이 정의되어 있다.

/usr/src/linux-2.6.23.8/scripts/Kbuild.include
126 build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj

 '.tmp_versions' 디렉토리 생성 부분에서 보았던 루틴이다. KBUILD_SRC가 정의되어 있으면 '
scripts/Makefile.build obj' 앞에 srctree 값을 붙여주고, 아니면 '-f scripts/Makefile.build obj'를 build에 넣는다. 지금 단계에서는 KBUILD_SRC가 정의되어 있지 않으므로, build에 '-f scripts/Makefile.build obj'가 들어간다.

Kbuild.include는 다음과 같이 커널 Makefile에 include 되어있다.

/usr/src/linux-2.6.23.8/Makefile
 278 include $(srctree)/scripts/Kbuild.include

 결국, 1221 line은 다음과 같이 치환된다.

make -f scripts/Makefile.build obj=/usr/src/example/scull

 매개변수 obj에 모듈의 경로를 넣어주고, scripts에 있는 Makefile.build를 실행한다. 해당 파일로 가보자.




이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/40 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/13 15:13
 저번주에 평소에 스터디를 진행하던 D모사에서 스터디를 할 수가 없어서, 스터디 장소 문제로 꽤나 고생을 하였다. 새삼 쾌적한 스터디 장소를 제공해 주시는 상민님께 감사하는 마음을 좀더 가지게 되었다. 저번주에 논의한대로 스터디 종료 시간이 앞당겨 졌기때문에, 스터디 시간을 늘리기 위해 스터디 시작시간을 오후 1시 30분으로 앞당기게 되었다.

오늘은 저번주에 분석을 끝냈는걸로 알고있었던 타이머 인터럽트 핸들러를 마저 분석하였고, start_kernel()의 vfs_caches_init_early(), mem_init(), kmem_cache_init()를 분석하였다. 

 저번주에 보았던 타이머 인터럽트 핸들러 루틴중에 update_process_times()scheduler_tick()run_posix_cpu_timers()를 미처 분석하지 못하였다. update_process_times()는 저번주에 분석한 내용대로, task와 관련되어 갱신해야 되는 루틴이다.

 scheduler_tick()는 스케쥴링과 관련된 생각보다 중요한 루틴이었다. 처음에 현재 cpu의 런큐(struct rq)를 가져오고, 현재 task의 sched_time과 last_ran, 현재 rq의 most_recent_timestamp를 갱신한다. sched_time은 스케쥴된 시간 정보를 나타내고, last_ran은 마지막으로 수행된 시간 정보를 나타낸다. rq의 most_recent_timestamp는 최근에 수행된 timestamp 값을 나타낸다. 그리고, 현재 프로세스가 idle 프로세스이면, wake_priority_sleeper()를 수행하고, 그외의 경우는 task_running_tick()를 수행한다.

 task_running_tick()는 task의 타임 슬라이스를 갱신해주고, 타임 슬라이스가 전부 소비된 task는 task의 우선순위에 따라 적절한 큐에 끝에 추가시켜주는 역활을 한다. 런큐는 active 큐와 expired 큐라는 두개의 큐가 존재한다. 우선 기본적으로 active 큐에 있는 task들을 수행하고, 타임슬라이스를 모두 소비한 task는 expired큐에 추가 시킨다. active큐에 있는 task를 모두 수행하였으면(active 큐가 비었으면), expired 큐와 active 큐의 포인터를 바꾼다. 그러면 expired가 active가 되고 active가 expired가 된다.

 그런데 task_running_tick()를 보면 실시간 task인 경우에는 타임 슬라이스를 모두 소비하더라도 무조건 active 큐에 추가 시킨다. 그리고 INTERACTIVE 한 task인 경우에도 active 큐에 바로 추가한다. 하지만 INTERACTIVE 한 task라도, expired 큐가 너무 오래동안 대기중이라면 expired 큐에 추가한다. 나머지 task들은 타임 슬라이스를 모두 소비하면 expired 큐에 추가 한다.

이후에 SMP 환경이면  scheduler_tick()는 rq의 부하를 갱신하고, 로드 밸런싱 할 시간이면 SOFTIRQ에 등록되어 있는 run_rebalance_domains()를 호출 하여 CPU간 로드 밸런싱을 한다.

run_posix_cpu_timers()는 현재 task에 등록된 POSIX 타이머가 실행 되어야 하면 해당 타이머를 실행 시켜주는 루틴이다. 이렇게 타이머 인터럽트 관련된 루틴의 분석은 모두 끝이 났다.

 vfs_caches_init_early()는 가상 파일 시스템(Vritual File System)를 쓰기위해 dentry 캐쉬와 inode의 해쉬 테이블을 생성해주는 루틴이다. 각각 dcache_init_early()와  inode_init_early()에서 초기화 되며, 내부적으로 alloc_large_system_hash()를 호출해서 해쉬 테이블을 생성한다.

 mem_init()는 free_all_bootmem()를 호출하여 node의 boot_mem_map에 있는 모든 영역을 해제하고, kclist_add()를 이용하여, /proc/kcore에 파일에 해당 메모리 정보를 추가 시켜 준다. 그리고 printk()로 현재 메모리 정보를 출력하고, SMP인 경우에는 boot_level4_pgt+1 페이지 테이블을 init_level4_pgt+1로 바꾸어 준다.

 kmem_cache_init()는 슬랩 할당자 관련 초기화 루틴이다. 다음 주에 슬랩 할당자에 관해서 좀더 공부를 한뒤 분석을 마저 하기로 하였다. 그래서 kmem_cache_init()에 대한 내용은 다음주에 포스팅 하도록 하겠다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/59 관련글 쓰기
Name
Password
Homepage
Secret
2007/12/07 15:57
 예전에 olly debugger 클론 디버거를 만든적이 있다. 그시절에 부족한 실력으로 무리를 해서 잘 마무리 한것같다. 짧은 기간에 나름 고난이도의 스킬을 익히면서 만드느라 아직 버그가 많이있다. 추후에 예전에 같이 프로젝트 했던 팀원(현재 같이 파이썬 스터디를 하고 있다)과 코드를 다듬어서 오픈소스로 전환할 예정이다.


사용자 삽입 이미지
< 그림1. only debugger>

작업 일지

2006년 4월 3일
< 오전 >
 책 보다가 병원갔다옴.
< 오후 >
프로젝트실 환경 셋팅, 디버거 참고자료 검토.
< 저녁 >
셋팅 끝, 참고자료 검토, only Debuger 디버거 제작 구상회의

2006년 4월 4일
< 오전 >
only Debugger 구현 계획서 작성
< 오후 >
강사님과 미팅, 참고 자료 검토, 명현 메모리 뷰어 약간 도움.
< 저녁 >
심볼 테이블, Break Point, Setp into 기능에 대한 회의, 자료를 봐도 이해가 안된다. 빡실듯...
디버거 기능 예제 작성 계획

2006년 4월 5일
< 오전 >
역어셈에 관련된 자료를 조사하였다. 그리고 원천기술 확보용 예제 작성을 위해 명현이가 어제 만든 소스 수정.
opcode table 독해 하고.--;; 밥먹으러 갈때쯤에 백신 제작자가 올려놓은 Intel i386 CPU명령어 분석 방법에 대한 문서 확보!
< 오후 >
오전에 획득한 문서를 바탕으로 ModR/M과 SIB Table이 있는 문서구하고 명령어 분석하는 방법에 대한 스킬 학습.
이제 Intel CPU 기계어를 볼수 있는 능력이 생겼다. 하지만 이걸 짤려면;; 상당히 노가다 일듯.
샘플 예제소스 작성 조금.
< 저녁 >
예제소스를 명령어 길이 구하는 부분에서 막막해서 대충 정리하고... 사실 명령어 길이는 명령어 전체를 분석해야 나오기 때문에;;
상당량의 작업을 요하는 부분이다. 그래서 그냥 1byte씩 어셈 출력하게 야메로 만들어 놓고;; Intel 기계어 읽는 방법에 대한
스킬을 정리 하였다.


2006년 4월 6일
< 오전 >
 break point에 관한 참고자료 검토. 개념은 잡았으나 구현이 잘안되었다.
< 오후 >
 참고 서적에 있는 소스 수정했더니 어느정도 돌아간다! 한참 삽질해서 구현을 하기는 하였다. 실용성 있게 수정이 필요할듯.
< 저녁 >
 오후에 만든 break point를 바탕으로 step into 구현 할려고 하였으나, 실패. 책에는 아주 간단하게 설명
되어있는데 왜 안되는건가! 내일 gdb 소스좀 보고 자료 조사하면서 삽질더 해보고 구현해야겠다.
step over랑 step out도 해야하는데...후~

2006년 4월 7일
< 오전 >
 아침에 오자마자 멍한 상태에서 명현이가 필받아서 같이 열심히 일했다;;
break point 확실히 구현하고 step into도 구현했다. 그리고 명현이가 stack 추적 기능(대박!) 을 구현해서 앞으로
상당한 진척이 있었다!
< 오후 >
 오전에 많이 해놔서 여유가 좀있었다. step out을 구현하였는데 그냥 현재 함수의 리턴주소에다가 브레이크 포인트를
걸고 해지하는 형식으로 step out을 간단히 구현할수 있었다. 나중에 좀더 검토해봐야할듯...
< 저녁 >
  오전, 오후에 break point, step 시리즈 구현을 해서 여유가 있어서 좀 느긋하게 심볼 테이블 삽질좀 하다가 dis asem 기능
구현해야 할것 같아서 gdb의 dis asem 소스를 조금 보았다. 오늘은 진척이 꽤나 있었던것 같다. 기본 기능은 거의 다 된듯..
 

2006년 4월 8일
< 오전 >
 회의. 내용은 이번주 동안 확보한 프로젝트를 진행하는데 필요한 확보한 원천기술. 구현하는데 풀어야할 몇가지 기술적인 난제들. 그리고 전체적인 프로그램 흐름과 모듈 설계를 하였다.
< 오후 >
 토요일이라 그런지 퍼져서 멍한 상태로 있다가, 프로그램에 쓸 아이콘 찾아보았다. 창일이가 찾은 아이콘 중에 좋은게 있었다!(올려놨음). UI 구현을 위해 MDI에 대한 예제를 작성 해보았다.

2006년 4월 10일
< 오전 >
gdb 소스 분석. 막막하다. 관련 루틴만 4500라인.
< 오후 >
필요한 부분만 빼올려고 시도. 몇가지 자료구조 빼왔으나 어찌쓸지 고민.
< 저녁 >
분석해가며 더이상 빼오기는거 포기하고 현재 가져온것만으로 수정할려고 시도. 방향을 잡을려고 했으니 역시 막막하다.
집에 갈때쯤 약간 감을 잡았으나 아직 짙은 안개. 오늘은 한일이 없는듯;;

2006년 4월 11일
< 오전 >
어제에 이어 gdb 소스와 씨름하다. 자료구조는 대강 알겠는데 함수들은 도저히 모르겠다. 도대체 어떻게 만들어 놓은거야!
< 오후 >
강사님과 미팅. 역어셈 모듈은 노가다이니까 일단 간단하게 구현해놓고 버전업 하는씩으로 하라고 하셨다.
다행이라면 다행이지만...gdb소스는 아무리 봐도 함수 구현부분은 이해가 잘 안된다. 4500 라인의 압박;;
그래서 gdb꺼 가져와서 수정할려는 생각을 접고. 아주 기본적인 자료구조만 받아와서 그냥 맨땅에
구현하기로 결심했다.
< 저녁 >
이렇게 마음이 편할수가! 좀 느리면 어떠리 일단 만들고 봐야지. 헤딩해가며 조금씩 구현하니 약간의 진척이 있는것 같다.
내일 열심히 하면 기본적인 어셈코드는 볼수 있을것 같다! 내일까지 다 구현하고 데이타 전송 방식 정하고 0.01 버전 모듈
완성해야겠다!

2006년 4월 12일
< 오전 >
어제 저녁부터 만들기 시작한 역어셈 모듈을 코딩. 니모닉 전부 다 수정했다. 어제 창일이가 만든 define 첨가하고 자료구조 수정.
< 오후 >
드디어 전체적인 구조가 완성되었다! 이제 남은건 타입에 따라(많다.--) 동작 방식을 코딩해주면 된다!
< 저녁 >
오후에 완성된 틀에 따라서 동작방식 코딩, 대략 100가지 동작방식이 있는것같다;; 반도 못한듯;;

2006년 4월 13일
< 오전 >
역어셈 모듈 작성. 속도가 붙는다!
< 오후 >
역어셈 모듈 대부분다 완성 이제 2바이트 opcode와 그룹 opcode만 남았다!
< 저녁 >
역어셈 모듈 완성하고 dll로 모듈 작성! 자잘한 버그 수정
 

2006년 4월 14일
< 오전 >
어제 만든 모듈 조금 만지작 거리고... 뭘 할까 한동안 생각했다. 참고자료 소스 분석 좀 했음.
< 오후 >
할일 없이 이것저것 만지작 거리다가 일거리 좀 얻어볼까하고 회의를 하였다. 모듈을 나눠야 했으나
모두 결합성이 높은 기능들이라 모듈을 나누기가 어려웠다.
< 저녁 >
임베디드 자료에 한참 빠져있다가...리소스 좀 빼오고 또 계속해서 할일에 대한 생각.
오늘은 생산성 0...

2006년 4월 15일
< 오전 >
 오랜만에 디버거 관련 소스를 보니 낯설다. 다시 적응하기 위해 소스 이리저리 뜯어보며 동작방식을 리마이닝 하였다.
심볼 테이블 삽질 조금.
< 오후 >
 삽질 마저하다가 서점가서 컴파일러 관련 서적을 봤는데 심볼 값 가져오는 내용은 없고 심볼테이블을 구성하는
알고리즘에 관한 내용만 있었다. 웹서핑 해가며 자료 찾아봐도 역시나 있을턱이 없다. msdn에만 조금 있었다. 역시 계속되는 삽질...
< 저녁 >
 다들 집에가고 명현이와 둘이 남아서 명현이는 UI 구현하고 나는 계속해서 삽질을 하였다. 하다가 드디어! CALL BACK 함수가 호출
되었다! '자 인제 금방 다하겠지' 라고 생각했건만... 안된다.-- 그래도 약간의 성과가 있으니 배도 고프고 해서 퇴근.

2006년 4월 17일
< 오전 >
break point list와 memry view에 쓸 소스 작성했다.
< 오후 >
대용량 메모리 로드시 뻗어버리는 문제 고민.
< 저녁 >
속도가 매우 느리다는점을 발견했다. 알고리즘 개선 고민.

2006년 4월 18일
< 오전 >
할일없이 시간만 보냈다;;
< 오후 >
역어셈 모듈 개선. 속도가 대폭 향상되었다!
기존의 러시아 페인트공 알고리즘을 삭제하고 한번에 삽입하는 코드로 수정하였다.
대용량 파일을 읽을수 있게 수정.
< 저녁 >
이리저리 빈둥거리다가 집에갈때쯤 가서야 log 정보 관련 코딩..

2006년 4월 19일
< 오전 >
어제 하다만 로그 관련 소스 날라갔다 ㅠㅠ. 처음부터 새로 작성 시작.
< 오후 >
모듈 이름 얻어오는곳에서 막혀서 고생하다. 도대체 어떻게 해야하는건가! 결국 msdn에서 관련 예제를 찾아서 그거 보고 해결. 하지만 실행파일 이름은 파일 읽을때 받아오기로 하였다.
< 저녁 >
조금 빈둥거리다가 로그 관련 소스 거의다 완성. 그리고 보니 메모리 뷰 관련소스도 수정을 좀 해야겠다. 조금더 좋은 방법이 생각났음.

2006년 4월 20일
< 오전 >
어제 로그관련 소스 DLL로 제작했음. 역어셈 모듈에 next_addr() 함수 추가. 메모리 뷰 소스 수정.
< 오후 >
프로그램이 로딩되는 시작주소 알아낼려고 애쓰다가 퍼짐.
도저히 유추를 못하겠다;;
< 저녁 >
밥먹고 조금 빈둥거리다가 PE관련 자료가 필요해서 명현이와 서점 방문. 이것저것 책 뒤적이다가 왔음. 서점 아저씨 눈초리가;;
집에갈때쯤되어서 execute moduels 관련 소스 작성. 다 짜긴했지만 테스트를 안해서 돌아걸런지;;
내일은 잡다한거 마저다하고 버그수정에 들어가야겠다!

2006년 4월 21일
< 오전 >
 작성할 문서 형태 만들고, execute module 관련 소스 올림.
< 오후 >
 UI 수정. icon 붙이고 MDI 차일드 타이틀바 달았음.
< 저녁 >
 문서 작성 조금.

2006년 4월 22일
< 오전 >
문서 작성 조금했음.
< 오후 >
강사님께 받은 자료로 심볼테이블 삽질하다가 포기-_-+
도대체 어떻게 하는거야! 누구 아는사람이 가르쳐 줬으면 좋겠네 ㅠㅠ
프로젝트 데드라인이 다 되어서 심볼 테이블 기능은 포기하로 하였다. 하지만 기본적인 디버거 기능은 모두 구현한듯 하다.
모두 수고~


이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://onestep.tistory.com/trackback/58 관련글 쓰기
Name
Password
Homepage
Secret
prev"" #1 #2 #3 #4 #5 ... #6 next