Recent Posts
Recent Comments
04-19 00:01
관리 메뉴

동글동글 라이프

Linux Kernel & Device Driver [3] 본문

개발자 이야기/Programming

Linux Kernel & Device Driver [3]

동글동글라이프 2010. 6. 24. 11:15

드디어 마지막 날입니다.

오늘의 배울 내용은 아래와 같습니다.


, 디바이스 드라이버.

- 파일시스템

(가상파일시스템, 다형성)

- 레이어드 개발법

- 커널 내 시스템 콜 추가

- 커널 모듈 프로그래밍

- 디바이스드라이버 개요

- 인터럽트, 문자 디바이스 드라이버 구현


파일 시스템을 어떤식으로 접근해서 알려주실지 기대가 됩니다^^

대부분 커널 소스를 직접 까면서 보여주시니

단순이 그림이 아닌 눈으로 보이는 부분이 확실하니

휘발성이 아닌 비 휘발성으로 머릿속에 오래 남아 있을 듯 하네요 :)




- cat 명령어 짜보기

1
2
3
4
5
6
7
8
9
10
11
12
#include <unistd.h>
#include <fcntl.h>
int main(void){

	int fd,ret;
        char buff[1024];
	fd = open("cat.c",O_RDONLY);
	while(ret = read(fd, buff, sizeof buff ) )
		write( 1, buff, ret);
	close(fd);
	return 0;
}

원본 소스 :  http://codepad.org/uJ0X8Bfh

원래 cat 은 키보드로 입력되어서 그 값을 출력하는 형태이기 때문에

while(ret = read( fd , buff, sizeof buff ) )
  write( 1, buff, ret);

이 소스에서 fd 가 아닌 키보드( 0 ) 으로 설정을 해야합니다.

그리고 파일을 지정하지말고 인자값으로 받아오기 위해서는

메인함수를 int main( int argc , char argv) 이와 같이 바꿔줘야 하며,

리다이렉션(redirection) 까지 되게 하기 위해서는

dup함수를 사용해야 합니다.

dup 함수는 JoinC에 잘 정의되어 있군요 :)

http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/system_programing/File/dup




커널에서 파일을 처리하는 구조체를 보면 아래와 같습니다.

http://lxr.linux.no/linux+v2.6.34/include/linux/fdtable.h#L43


/*
* The embedded_fd_set is a small fd_set,
* suitable for most tasks (which open <= BITS_PER_LONG files)
*/
struct embedded_fd_set {
        unsigned long fds_bits[1];
};

struct fdtable {
        unsigned int max_fds;
        struct file ** fd;      /* current fd array */
        fd_set *close_on_exec;
        fd_set *open_fds;
        struct rcu_head rcu;
        struct fdtable *next;
};

/*
 * Open file table structure
 */
struct files_struct {
  /*
   * read mostly part
   */
        atomic_t count;
        struct fdtable *fdt;
        struct fdtable fdtab;
  /*
   * written part on a separate cache line in SMP
   */
        spinlock_t file_lock ____cacheline_aligned_in_smp;
        int next_fd;
        struct embedded_fd_set close_on_exec_init;
        struct embedded_fd_set open_fds_init;
        struct file * fd_array[NR_OPEN_DEFAULT];
};

여기서 중요한건 struct file ** fd 부분입니다.

실제로 파일에 대한 포인터가 여기에 담겨있고 이것을 사용하여 파일을 다룹니다.

위의 소스코드에서 read 함수가 일어났다면 sys_read 함수를 호출하게 되는데

sys_read(3,buff,1024);라고 한다면

결국 2중 포인터인 fd 가 fd[3] 을 호출하게 됩니다.

fd 자체가 file 구조체의 2중 포인터 변수이기 때문에 

file 구조체도 한번 살펴봐야 합니다.

file 구조체는 http://lxr.linux.no/linux+v2.6.34/include/linux/fs.h#L913

여기서 확인할 수 있으며

여기서 가장 중요한 3개의 값만 확인하면 됩니다.


unsigned int            f_flags;   
fmode_t                 f_mode;   // 현재 모드 read 혹은 write 모드
loff_t                  f_pos;         // 파일의 현재 위치

flag 설명을 놓쳤.. ㅡ_ㅠ

그리고 이 구조체의 마지막 에는 inode 값을 가지고 있으며,

이 inode 값은 모두 같은 inode 값을 가지고 있습니다.

inode 구조체에 대한 설명은 인터넷에 많으니 패스~


- Tip 1

파일을 read함수로 읽어올 때 파일의 끝이 EOF 일때를 체크하여 파일을 읽어오는 것이 아닙니다.

거대한 정보 구조체 inode에서 확인해 보면 i_size 라는 값이 있는데

이 값을 이용하여 읽은 사이즈와 전체 사이즈를 계속 비교하면서 그 값이 0이 될때

파일을 그만 읽어야 하는지 판단합니다.



- inode 구조체 안의 i_mode 의 16비트 플래그

16비트의 플래그를 그림과 함께 잘 설명해 주셨습니다.

파일 모드 : 파일과 관계된 접근과 실행 권한을 저장하는 16비트 플래그

비트 내용
12-14 파일 형식(일반, 디렉터리, 문자 또는 블록 특별, 선입선출 파이프)
9-11 실행 플래그
8 소유자 읽기 허가
7 소유자 쓰기 허가
6 소유자 실행 허가
5 그룹 읽기 허가
4 그룹 쓰기 허가
3 그룹 실행 허가
2 다른 사용자 읽기 허가
1 다른 사용자 쓰기 허가
0 다른 사용자 실행 허가

출처 : 위키피디아 - http://ko.wikipedia.org/wiki/%EC%95%84%EC%9D%B4%EB%85%B8%EB%93%9C

직접 파일을 일일이 설정하시면서 설명해 주셨는데

9~11 까지의 실행 플래그는 setuid, setgid , sticky bit 를 의미하며

이 비트를 켜고 끄는 이유에 대해서도 이야기를 들었습니다.




- 디렉토리는 하드링크를 걸수 없다(?)


ls 명령어 중 재귀 호출을 하는 -R 명령을 이용하면

모든 디렉토리의 값들을 다 보여주기 때문에

디렉토리에 하드링크를 걸어버리면 이 옵션에서 무한 반복이 돌게 됩니다.

그래서 디렉토리는 -S 심볼릭 링크를 걸어야 합니다.



마지막 날이라

커널 컴파일을 한 뒤에 부팅까지 하는 부분도 보여주셨는데

역시 어떻게 튈지 모르는 부분이라 조심스럽게 부팅을 시키셨습니다. :)



3일동안의 강의가 끝났습니다.

강사님의 무한한 지식을 확인할 수 있었고,

커널에 대한 기반지식을 가지게 되었습니다.

수업에 월드컵도 있었고,

서울이 연고지가 아니기에

집중력이 좀 덜하지 않나.. 하는 아쉬움이 있네요^^;





강의를 해주신 김정인 강사님께 정말 감사드립니다.



Comments