함수의 메모리 주소를 알고 싶으면 System.map 파일을 확인해보면된다 // 일종의 심볼테이블
====================================================================================================================================================
리눅스 시스템 호출
read, write, open 등의 함수들을 호출했을 때 인터럽트 0x80번이 호출되는데..이렇게 되면 구분을 할수 없다
그래서 호출 전에 함수에 대응되는 인식 번호 를 먼저 읽어 들여서 찾아간다.
시스템 호출 흐름의 예
1. 사용자 프로세스에서 시스템 호출 사용(open())
2. C 언어 라이브러리(libc)에서 시스템 호출 준비
시스템 호출에 필요한 인자를 register stack에 넣음
시스템 호출 번호 저장
인터럽트 발생(0x80)
3. system_call()
IDT에 의해 인터럽트 시작
sys_call_table 사용
인터럽트 서비스 루틴 실행
4. 결과값 사용자에게 반환
ex) fork()함수 호출 흐름 - fork() 함수는 자기 호출 할때 마다 자기자신을 복사한다
--> user task(fork() 호출)
--> libc.c(호출된 함수의 번호를 저장(fork()는 2번), 0x80인터럽트 발생)
--> IDT(system_call() 실행) // 어셈블리에서 ENTRY(system_call) 로 정의
--> systme_call_table(2.4커널에선 arch/i386/kernel/entry.S에 정의, libc.c에서 저장한 호출번호를 참고로 함수 호출)
어셈블리와 C 언어로 바라본 시스템 호출
C - 이건 별로 설명할게 없으니 패스~
#include <unistd.h>
int main(void)
{
write(1, "Hello, Kernel\n", 14);
return 0;
}
======================================================================================================================
어셈블리
section .data
hello: db 'Hello, Kernel', 10 // 어셈블리에서는 \n를 사용할수 없기 때문에 '문자열' 후에 엔터의 아스키코드 10을 직접입력
helloLen: equ $-hello // $는 현재 메모리 주소, 즉 현재위치 - 문자열 시작 주소 = 문자열의 길이
// 바로 문자열의 길이를 넣어줘도 되지만 문자열이 변경됬을때 따로 수정할 필요가 없다.
section .text
global_start
_start:
// 지금부터 write 함수
mov eax, 4 // writ(sys_write) 의 시스템 호출 번호 저장
mov ebx, 1 // stdout을 의미하는 1
mov ecx, hello // 문자열
mov edx, helloLen // 문자열 길이
int 80h // 인터럽트 0x80 발생 -> IDT(Interrupt Descriptor Table) 의 system_call() 에 의해 함수 호출
mov eax, 1 // exit(sys_exit)의 시스템 호출 번호
mov ebx, 0 // exit(0), 종료코드를 0으로 설정
int 80h ; 0x80발생
tip) 시스템 호출 테이블은 sys_call_table에 정의 되어 있으며
2.4.32 커널 - [arch/i386/kernel/entry.S]
2.6.32 커널 - [arch/i386/kernel/syscall_table.S]
에 서 찾아 볼수 있다.
======================================================================================================================
링크 거는법
[ln -s/(경로)/(파일) (링크이름)] - [ln -s /mnt/hgfs/src/linux-2.* linux-2.*]
======================================================================================================================
공유 폴더에서 커널(2.4) 컴파일 하기
linux-2.4.32 를 공유폴더에 옮긴다음
공유폴더의 linux-2.4.32 에서 make clean 한다음(기존에 link 되있는것을 삭제)
공유폴더의 linux-2.4.32 - include 폴더에서 asm-i386 을 asm 으로 복사해놓고 [cp -r asm-i386/ asm]
그리고 다시 linux-2.4.32 폴더로 돌아와서 Make file 을 수정한다 (300, 301 line을 주석처리해준다)
그다음 다시 make menuconfig 등 커널 빌드...
======================================================================================================================
공유 폴더에서 커널(2.6) 컴파일 하기
기존에 있던것을 mv명령으로 옮겼더니 오류가 생기네요 그래서 커널 압축파일을 바로 공유폴더에 넣어서 새로 컴파일 했습니다.
1. make mrproper
2. make menuconfig
3. makefile 을 수정
865 line 을 주석 처리 하고
866 line 에 [@cp -r include/asm-$(ARCH) include/asm] 을 추가 시켜준다.
1293 line 에 있는 rm -r 을 [rm -rf]로 수정
make 를 수정한후에 실행 해도 에러가 나는데
이유는 asm-i386은 100개라고 가정하면 menuconfig후엔 2개의 파일이 추가되어 102개가 된다
make에선 asm 파일을 참조하기 때문에 2개의 추가된 헤더 파일을 찾지 못한다 그래서
include 경로에 가서 asm을 지우고 102개가된 asm-i386으로 다시 바꿔주면 된다.
[rm -rf asm]
[cp -r asm-i386 asm]
그리고 다시 make & 무한 대기~
'코스웨어 > 12년 내장형하드웨어' 카테고리의 다른 글
[RFID] 10.11 업무일지 - 정철 (2) | 2012.10.11 |
---|---|
[RFID]10월 11 일 수업 (5) | 2012.10.11 |
Visual Studio 에서 사용 팁. 나름 유용하니 애용하시오. (4) | 2012.10.11 |
[RFID] - 정철 (0) | 2012.10.11 |
[리눅스 커널]linux 2.4 & linux 2.6 소스인사이드 설정 (10) | 2012.10.10 |
-리눅스 시스템 호출, “NTFS 에서 커널 빌드과정중 에러 대처- (8) | 2012.10.10 |
2010.10.10 오전[리눅스 시스템호출, 예제소스] (14) | 2012.10.10 |
리눅스 커널 2.4 분석하기(소스인사이트에 커널소스추가) (4) | 2012.10.10 |