Recent Posts
Recent Comments
Link
01-11 00:00
동글동글 라이프
Linux Kernel & Device Driver [3] 본문
드디어 마지막 날입니다.
오늘의 배울 내용은 아래와 같습니다.
파일, 디바이스 드라이버.
- 파일시스템
(가상파일시스템, 다형성)
- 레이어드 개발법
- 커널 내 시스템 콜 추가
- 커널 모듈 프로그래밍
- 디바이스드라이버 개요
- 인터럽트, 문자 디바이스 드라이버 구현
파일 시스템을 어떤식으로 접근해서 알려주실지 기대가 됩니다^^
대부분 커널 소스를 직접 까면서 보여주시니
단순이 그림이 아닌 눈으로 보이는 부분이 확실하니
휘발성이 아닌 비 휘발성으로 머릿속에 오래 남아 있을 듯 하네요 :)
- cat 명령어 짜보기
#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];
};
* 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개의 값만 확인하면 됩니다.
flag 설명을 놓쳤.. ㅡ_ㅠ
그리고 이 구조체의 마지막 에는 inode 값을 가지고 있으며,
이 inode 값은 모두 같은 inode 값을 가지고 있습니다.
inode 구조체에 대한 설명은 인터넷에 많으니 패스~
- Tip 1
파일을 read함수로 읽어올 때 파일의 끝이 EOF 일때를 체크하여 파일을 읽어오는 것이 아닙니다.
거대한 정보 구조체 inode에서 확인해 보면 i_size 라는 값이 있는데
이 값을 이용하여 읽은 사이즈와 전체 사이즈를 계속 비교하면서 그 값이 0이 될때
파일을 그만 읽어야 하는지 판단합니다.
거대한 정보 구조체 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일동안의 강의가 끝났습니다.
강사님의 무한한 지식을 확인할 수 있었고,
커널에 대한 기반지식을 가지게 되었습니다.
수업에 월드컵도 있었고,
서울이 연고지가 아니기에
집중력이 좀 덜하지 않나.. 하는 아쉬움이 있네요^^;
강의를 해주신 김정인 강사님께 정말 감사드립니다.
'개발자 이야기 > Programming' 카테고리의 다른 글
C언어 문제 - 해결방안 (4) | 2010.08.05 |
---|---|
C언어 문제 (3) | 2010.08.04 |
Linux Kernel & Device Driver [2] (5) | 2010.06.23 |
Linux Kernel & Device Driver [1] (5) | 2010.06.22 |
삼성소프트웨어멤버십에서 2010년도 하반기 신입회원을 선발 합니다. (1) | 2010.05.19 |
Comments