Transcript Document
리눅스 커널 분석 강사명 : 김정인 email : [email protected] 수업자료 ( 소스 / ppt 자료 ) ftp server : 156.147.178.179 id/passwd : linux / linux 강의 배포자료 : 이동식 디스크 ( 커널수업자료.egg ) 리눅스 커널 분석 1. 완벽한 C 언어 2. 커널 고급 자료구조 ( generic linked list, hash, RB Tree ) 3. 리눅스 시스템 프로그램 ( R. stevens ) 4. 네크워크 프로그램 ( R. stevens ) 5. 가상 파일 시스템 ( file system, driver , inode, file, ... ) 6. 프로세스 ( schedule , context switching , fork, exit, wait.. 7. 메모리 ( paging , buddy system, slab allocator ) 리눅스 커널 분석 # ls -l # touch aaa # ls -li 475194 -rw-r--r-- 1 root root 0 2012-11-06 15:12 # mknod mydev c 200 0 struct inode {}; i_ino i_mode i_nlink i_uid i_gid i_size i_rdev 2012-11-06 i_mtime 475194 brw-r--r-1 root root 0 200,0 mode owner group other 1 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 - s s t r w x r - - r - - r w S r - - r - r w s r - - r - r w - r - - r - - uid => 0 => "root" # vi /etc/passwd root:x:0:0:root:/root:/bin/bash pwd = getpwuid(0); struct passwd { char *pw_name; char *pw_passwd; uid_t pw_uid; gid_t pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell; }; /* /* /* /* /* /* /* u u u g r h s gid => 0 => "root" # vi /etc/group root:x:0 grp = getgrgid(0); struct group { char *gr_name; char *gr_passwd; gid_t gr_gid; char **gr_mem; }; /* /* /* /* g g g g epoch : 1970년 1월 1일 자정으로부터 현재 까지 흘러온 초 단위의 시간 1352248716 tmp = localtime( &time_t ); struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; /* /* /* /* /* /* /* /* /* second minute hours day of month year * day of day in daylig struct dirent *p; p = readdir(dp); struct dirent { ino_t d_ino; off_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; }; / / / / / d SB inode data hello world i_ino i_mode i_nlink i_uid i_gid i_size i_rdev 2012-11-06 i_mtime 475194 brw-r--r-1 root root 0 200,0 root => linux => aaa => 4 4kb hello dentry aaa 475194 /root/20121107/aaa ./aaa i_ino i_mode i_nlink i_uid i_gid i_size i_rdev 2012-11-06 i_mtime 475194 brw-r--r-1 root root 0 200,0 root => linux => aaa => 4 4kb hello mode owner group other 1 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 - s s t r w x r - - r - - set-user-id bit 0 login ID => effective user id set-user-id bit 1 owner ID => effective user id mode owner group other 1 0 0 0 0 0 1 1 1 0 1 0 0 1 0 0 - 스티키( : s s t r w x r - - r - sticky ) 비트 set 해당 디렉토리에서는 파일의 소유자만이 파일을 지울수 있다. # cp aaa bbb aaa 475194 bbb 475211 475194 i_ino -rw-r--r-- i_mode 475211 1 i_nlink -rw-r--r-root i_uid root1 i_gid 0root i_size root i_rdev 200,0 6 0 i_mtime 6 2012-11-06 4kb hello 4kb world # ln aaa bbb # rm aaa # mv aaa bbb bbb 475194 // link() // unlink() 475194 -rw-r--r-1 root root 6 0 i_ino i_mode i_nlink i_uid i_gid i_size i_rdev i_mtime 4kb 하드링크의 제약 world 1. 같은 파티션에서만 하드링크가 가능함 2. 디렉토리는 하드링크 할수 없다. 예외) 시스템은 ., ..에 대해서만 하드링크 한다.(상대경로) # ln -s aaa bbb aaa 475194 bbb 65537 // symlink() 475194 i_ino 65537 i_mode -rw-r--r-lrwxrwxrwx 1 i_nlink root1 i_uid root root i_gid 6root i_size 0 3 i_rdev 0 i_mtime 4kb hello 4kb aaa struct _IO_FILE *fp = fopen("aaa", "r"); while( (ch = fgetc(fp)) != EOF ) ... FILE fp 0x9c83008 0 _flags _IO_read_ptr _IO_read_end _IO_read_base \\ world n0 library buffer : 40 #include <stdio.h> int main(int argc, char **argv) { FILE *fp; char ch; fp = fopen( argv[1], "r" ); while( (ch = fgetc(fp)) != EOF ) printf("%c", ch ); fclose(fp); return 0; } #include <fcntl.h> int main(int argc, char **argv) { int fd; char ch; fd = open( argv[1], O_RDONLY ); while( read( fd, &ch , 1 ) ) write( 1, &ch , 1 ); close(fd); return 0; } 00000 int fd = open("aaa", O_RDONLY ); // int 80h eax , 5 // swi 90005 1. interrupt 2. exception 3. system call fffff 0000 ffff syscall table SYSCALL_DEFINE3(open, const char __user *, f sys_##fname sys_open(); 00000 int fd = open("aaa", O_RDONLY ); // int 80h eax , 5 // swi 90005 read(fd, &ch, 1 ); 1. interrupt write(1, &ch, 1 ); 2. exception close(fd); 3. system call fffff 0000 ffff task_struct 0 1 2 3 fd_array 1 3 file 1 dentry 1 1 ino 00000 close(1); dup(dst); // fd_array[1] = 0; // fd_array[1] = fd_array[3]; printf("hello world\n"); // write( 1, buff fffff 0000 ffff task_struct 0 1 2 3 fd_array 2 3 file 1 dentry 1 1 ino 00000 fd1 = open("xxx", O_RDONLY); fd2 = open("xxx", O_RDONLY); read( fd1, buff, 2 ); write( 1, buff, 2 ); getchar(); read( fd2, buff, 2 ); write( 1, buff, 2 ); fffff 0000 ffff task_struct 0 1 2 3 4 fd_array 1 2 2 1 file 1 ino 00000 fd1 = open("xxx", O_RDONLY); getchar(); read( fd1, buff, 2 ); write( 1, buff, 2 ); fd1 = ope getchar() read( fd1 write( 1, fffff 0000 ffff task_struct 0 1 2 3 1 0 2 1 file 1 ino task_struct 0 1 grep int fd[2]; pipe( fd ); 0 1 2 3 4 hello ps 0 1 2 3 4 if( fork()==0 ) { close(fd[0]); close(1); dup(fd[1]); close(fd[1]); } else { close(fd[1]); close(0); dup(fd[0]); close(fd[0]); } fd = open( "aaa", O_RDONLY ); fd = open( "dir", O_RDONLY ); fd = open( "mydev", O_RDONLY ); do_filp_open(); nameidata_to_filp(); __dentry_open(); f->f_op = fops_get(inode->i_fop); open = f->f_op->open; open(); chrdev_open(); filp->f_op = fops_get(p->ops); filp->f_op->open(inode,filp); misc_open(); file->f_op = new_fops; file->f_op->open(inode,file); my_open(); 함수 포인터 세팅 시점 do_mount();