Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)

Slides:



Advertisements
Similar presentations
1 장 Unix/Linux 소개 1 Helpers. 1 장 내용 1. 왜 유닉스인가 ? 2. 유닉스 시스템 구조 3. 유닉스 역사 및 버전 4. 리눅스 설치 ( 별도 2 시간 실습 ) 5. 사용 환경 6. 사용자 계정 관리 Unix/Linux 2.
Advertisements

YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
Basic of Buffer Over Flow
SYSTEM CALL (Syscall) CSLAB SEWON PARK.
임베디드 시스템 개발을 위한 리눅스 환경설정.
6 레이스 컨디션.
FTP 09 SPARCS 박철웅 [dothack].
4. 시스템 관리 기본 naldo.
Linux University of Seoul Computer Science Park Jong wook
제6장 FUSING.
PXA270 개발환경 설정 Ubuntu 실습용.
크로스 컴파일 환경 구축.
Linux System Programming
Kernel Programming Kernel
Kernel Porting Lecture #7.
System Call Linux Kernel 수업 3번째.
제4장 Cross Compiler 설치.
FUSING.
임베디드 프로그래밍 Lecture #
디바이스 드라이버.
디바이스 드라이버 개요 가상 디바이스드라이버 실습
Department of Computer Engineering
Tftp, nfs, samba 실습 임베디드 시스템 I.
Network Lab. Seoung Hyeon, Lee
목차 커널의 개념 및 기능 커널 포팅 램디스크.
6 프로세스 생성과 실행.
Linux System Programming
부 록 Ubuntu 설치.
System Call 구현 기초 (since 2004) (교재에는 7th 2006에 포함)
FND (Flexible Numeric Display)
Embedded System Porting (2)
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
리눅스 명령어 실습 임베디드 시스템 I.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 02. 프로그램의 기본구성.
Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)
Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
멀티쓰레드 기반의 서버구현 School of Electronics and Information.
5. 네트워킹 사용자 표시 : users/ rusers/who/w users 지역 호스트 상에 있는 사용자의 간단한 목록 표시
Internet Protocol and Programming
Term Project Team Member
Operating System 5주차 - System Call Analysis -
Geek-OS Project 정영진
6장 파일 및 레코드 잠금.
커널 모듈 프로그래밍 (Kernel Module Programming)
System Call 구현 기초 Linux 커널의 새로운 시스템 호출 구현은 아래 두 가지 작업으로 구성 커널 수정
실시간 자원 량 정보 제공을 결합한 Heartbeat
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
5 프로세스 정보.
adopted from KNK C Programming : A Modern Approach
문자 디바이스 드라이버 임베디드 시스템.
Kernel Programming Environment
4장 서버 구축을 위해 알아야 할 핵심 개념과 명령어
Internet Protocol and Programming
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
운영체제 RaspberryPi Sejin Oh.
Stepper Motor 디바이스 드라이버
Operating System Multiple Access Chatting Program using Multithread
Department of Computer Engineering
Kernel Programming Kernel
Execution with Unnecessary Privileges
GDB - GNU Debugger 김진용.
Internet Protocol and Programming
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
2015 OS Linux Kernel Programming
argc, argv 의 사용방법 #include <stdio.h>
C.
이성준 Library 만들기 이성준
Presentation transcript:

Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~) ※ 부팅 grub menu의 generic Linux “운영체제”를 선택하여 stu 로그인 (입력: stu415) Linux 커널의 새로운 시스템 호출 구현은 아래 두 가지 작업으로 구성 커널 수정 시스템 호출 번호 할당 커널 영역: vi /usr/src/mylinux/arch/x86/include/asm/unistd_64.h 유저 영역: vi /usr/include/x86_64-linux-gnu/asm/unistd_64.h 시스템 호출 테이블 등록: vi /usr/src/mylinux/arch/x86/kernel/syscall_table_32.S 시스템 호출 함수 등록: vi /usr/src/mylinux/include/linux/syscalls.h 시스템 호출 처리 함수 구현: newsyscall.c, newsysadd.c, getstat.c 커널 컴파일: make bzImage 모듈 컴파일: make modules, make modules_install 커널 설치: make install 재부팅: reboot 새로운 시스템 호출을 이용하는 사용자 수준 응용 시스템 호출을 사용하는 프로그램 작성: test1.c, test2.c, test3.c (라이브러리 작성: optional)

네트워크 설정 윈도우 환경에서 컴퓨터 네트워크 설정 값을 확인한다 (Windows) C:\WINDOWS\system32\ipconfig.exe /all (Linux) $ ifconfig -a 시스템 설정에서 네트워크를 클릭한다 네트워크 옵션 유선을 선택한다 2000 운영체제

네트워크 설정 IPV4 탭을 선택한다 네트워크 설정 값들을 입력한 후 저장한다 IP : 10.80.77.84 ~ 131 넷마스크 : 255.255.255.0 게이트웨이: 10.80.77.254 DNS 서버 : 117.16.191.6 ※ 네트워크 설정 값 확인  Windows: ipconfig 또는 Linux: ifconfig 2000 운영체제

ppt reader 설치: $ yum install @libreoffice 커널 소스 다운로드 ※ 모든 작업은 “super user (root)” 권한으로 수행해야 합니다! $ su [Enter] (입력: unixlinux) 또는 $ sudo su 커널을 수정하기 위해서는 커널 소스 필요 # cd /usr/src 디렉토리로 이동 커널 다운로드 # ftp ftp.kernel.org id: anonymous password: [Enter] ftp> binary ftp> cd pub/linux/kernel/v3.x ftp> get linux-3.2.37.tar.gz 다운 받은 커널 소스를 압축해제 # tar xvfz linux-3.2.37.tar.gz 설치한 소스 디렉토리를 mylinux로 심볼릭 링크로 연결 # ln –s linux-3.2.37 mylinux ppt reader 설치: $ yum install @libreoffice

커널 버전 번호 커널 버전의 의미 <Major> 커널에 커다란 변화가 있을 때 바뀌는 번호 <Minor> 짝수일 때 안정 버전, 홀수일 때 개발버전 <Build> 패치 레벨을 나타내는 숫자 <Revision> 개정 횟수를 나타내는 숫자 커널 버전: 3.6.37을 사용

시스템 호출 과정 ENTRY(system_call) /*arch/x86/kernel/entry_32.S 502*/ main SAVE_ALL …. call *sys_call_table(,%eax,4) main { … syscall (__NR_newsyscall); } IDT(IVT) 0x0 divide_error() degug() nmi() ENTRY(sys_call_table) /*arch/x86/kernel/syscall_table_32.S*/ … 1 2 3 4 sys_restart_syscall() … syscall() { movl 312, %eax int $0x80 } 0x80 system_call() sys_exit() /*real handler*/ asmlinkage int sys_newsyscall() { printk(…); } … sys_fork() sys_read() sys_write() 312 sys_newsyscall() IDT: Interrupt Descriptor Table = IVT: Interrrupt Vector Table 커널 영역: /usr/src/mylinux/arch/x86/include/asm/unistd_64.h 유저 영역: /usr/include/x86_64-linux-gnu/asm/unistd_64.h

(참고) syscall() /usr/include/unistd.h line 1176/ extern long int syscall (long int __sysno, ...) __THROW; /usr/src/mylinux/arch/x86/um/shared/sysdep/stub_32.h line 15 static inline long stub_syscall0(long syscall) { long ret; __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); return ret; } static inline long stub_syscall1(long syscall, long arg1){ __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); static inline long stub_syscall2(long syscall, long arg1, long arg2) __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), "c" (arg2)); …

커널 수정 (1) 64비트 (Ubuntu 64비트) 커널 영역 시스템 호출 번호 할당 Linux 커널이 제공하는 시스템 호출은 각각 고유한 번호를 갖는다 ①# su 명령으로 root 권환 획득 ②# vi /usr/src/mylinux/arch/x86/include/asm/unistd_64.h 파일 수정 또는 # gedit /usr/src/mylinux/arch/x86/include/asm/unistd_64.h 312번 __NR_newsyscall 추가

커널 수정 (2) 64비트 (Ubuntu 64비트) 유저 영역시스템 호출 번호 할당 Linux 커널이 제공하는 시스템 호출은 각각 고유한 번호를 갖는다 ② # vi /usr/include/x86_64-linux-gnu/asm/unistd_64.h 파일 수정 312번 __NR_newsyscall 추가

커널 수정 (3) 64비트 시스템 호출 테이블 등록 (32비트 64비트 동일) 시스템 호출 처리 함수를 sys_call_table 테이블에 등록 ③ # vi /usr/src/mylinux/arch/x86/kernel/syscall_table_32.S 에 등록

커널 수정 (4) 64비트 시스템 호출 함수 등록 (32비트 64비트 동일) ④ # vi /usr/src/mylinux/include/linux/syscalls.h 에 등록

커널 수정 (5) 시스템 호출 처리 함수 구현 일반 적으로 태스크 관리자 관련 함수는 /usr/src/mylinux/kernel/ 에 구현 파일 시스템 관련 함수는 /usr/src/mylinux/fs/ 밑에 구현 ⑤ # vi /usr/src/mylinux/kernel/newsyscall.c 코딩 /* 커널 코드 /usr/src/mylinux/kernel/newsyscall.c 코딩 */ #include <linux/linkage.h> #include <asm/uaccess.h> asmlinkage int sys_newsyscall() { printk("Hello Linux, 1234567 Sung MeeYoung is in Kernel\n"); /* write your name in English */ return 0; }

커널 수정 (6) ⑥ # vi /usr/src/mylinux/kernel/Makefile 수정 (32비트 64비트 동일) obj -y = 라인에 newsyscall.o 추가

커널 수정 (7~10) 커널 구성 ⑦ # cd /usr/src/mylinux (커널 소스의 상위 디렉토리로 이동) ⑧ # make mrproper (기존의 커널 설정 제거) 커널 버전 2.6부터 make dep 과 make clean 불필요 ⑨ # make menuconfig (범용적 커널 설정 스크립트 실행) 오류 나면 # yum –y install ncurses* 설치 옵션은 아래 사이트 참고 http://doc.kldp.org/KoreanDoc/html/Kernel24_Intro-KLDP/Kernel24_Intro-KLDP- 2.html (또는) # cp ../linux-headers-3.5.0-23-generic/.config ./ # make oldconfig (실행후 선택문 모두 엔터) 커널 컴파일 ⑩ # make bzImage (컴파일, 새 커널 생성)

커널 수정 (11~14) 모듈 컴파일 및 인스톨 모듈로 구성된 커널 내부 구성 요소를 알려주고, 이후 구성 요소들이 사용될 때 자동으로 커널에 적재되게 함 ⑪ # make modules (모듈 컴파일) ⑫ # make modules_install (모듈 인스톨) 새 커널을 /boot 디렉토리에 설치 ⑬ # make install (아래 작업 자동 수행) [ # cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 ] [ # cp System.map /boot/System.map-3.2.37 (새 System.map으로 대치 ) ] Install한 커널로 들어가기 ⑭ # reboot 재부팅 후 grub 선택 메뉴에서 3번째 previous Linux 선택 후 linux-3.2.37 선택 실습 1: newsyscall() 사용자 수준 응용 코딩 & 컴파일 & 실행하여 결과 확인

실습 1: newsyscall() /* 사용자 수준 응용 test1.c 작성 $ vi test1.c $ sudo gedit test1.c */ #include <linux/unistd.h> #include <errno.h> #include <stdio.h> main() { int i; i=syscall(__NR_newsyscall); printf("%d\n", i); } 컴파일: $ gcc test1.c –o test1 실행: $ ./test1 결과 확인 방법 $ dmesg | tail (참고) 라이브러리 작성(선택사항) /* contents of newsys.c */ …독립된 파일 #include <linux/unistd.h> #include <errno.h> call() { return syscall(__NR_newsyscall); } /* contents of test.c */ …독립된 파일 main() int i; i = call(); $ gcc –c newsys.c $ ar –r libnew.a newsys.o $ ranlib libnew.a $ vi test.c $ gcc test.c –L /root(libnew.a 있는 디렉토리) -lnew $ ./a.out

sys_gettaskinfo() 라는 커널 정보를 커널 모드에서 출력하는 새로운 313번 시스템 호출 구현 실습 2: newsysadd() sys_gettaskinfo() 라는 커널 정보를 커널 모드에서 출력하는 새로운 313번 시스템 호출 구현 /* 시스템 호출 처리함수 newsysadd() */ $ vi /usr/src/mylinux/kernel/newsysadd.c #include <linux/linkage.h> /*asmlinkage*/ #include <linux/kernel.h> /*printk*/ #include <../arch/x86/include/asm/uaccess.h> /*put_user*/ asmlinkage int sys_newsysadd(int a, int b, int *to_user) { int sum = 0; printk("(Kernel Message) a = %d, b = %d\n", a, b); sum = a + b; put_user(sum, to_user); return 0; } /* 사용자 응용 test2.c 작성 */ #include <linux/unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> main(void) { int i, a = 100, b = 200, from_kernel; i=syscall(__NR_newsysadd, a, b, &from_kernel); printf("from_kernel = %d\n", from_kernel); printf("syscall return value = %d\n", i, __NR_newsysadd); printf("__NR_newsysadd = %d\n", i, __NR_newsysadd); return 0; } (컴파일 ) $ gcc test2.c –o test2 (실행) $ ./test2 /* 새 커널 구성 않고 시스템 호출만 추가 */ $ make bzImage $ cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 $ reboot

(참고) 실습 2: gettaskinfo() sys_gettaskinfo() 라는 커널 정보를 커널 모드에서 출력하는 새로운 313번 시스템 호출 구현 /* 시스템 호출 처리함수 gettaskinfo() */ $ vi /usr/src/mylinux/kernel/gettaskinfo.c #include <linux/linkage.h> #include <linux/unistd.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/sched.h> asmlinkage int sys_gettaskinfo() { int i,cnt =0; printk("PID: %d\n",current->pid); printk("PPID: %d\n",current->parent->pid); if(current->state == -1) printk("Unrunable state\n"); else if (current->state == 0) printk("Runable state\n"); else if (current->state == 1) printk("Interruptable state\n"); else if (current->state == 2) printk("Uninterruptable state\n"); else if (current->state == 4) printk("Stopped state\n"); else if (current->state == 8) printk("Zombie state\n"); else if (current->state == 16) printk("Dead state\n"); else printk("Unkown sate\n"); printk("Priority: %lu\n", current->rt_priority); printk("Scheduling Policy: %lu\n",current->policy); printk("User CPU time: %lu ticks\n", current->utime); printk("System CPU time: %lu ticks\n", current->stime); printk("Start time: %lu \n", current->start_time); printk("Number of major faults: %lu\n", current->maj_flt); printk("NUmber of minot faults: %lu\n", current->min_flt); return(0); } /* 사용자 응용 test2.c 작성 */ #include <linux/unistd.h> #include <stdio.h> #include <errno.h> #include <sys/syscall.h> main() { int i; i=syscall(__NR_gettaskinfo); printf("%d\n", i); } (컴파일 ) $ gcc test2.c –o test2 (실행) $ ./test2 /* 새 커널 구성 않고 시스템 호출만 추가 */ $ make bzImage $ cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 $ reboot

태스크 리스트 current(/usr/src/kernels/mylinux/arch/x86/include/asm/current.h 17행) 전역 변수가 task_struct (/usr/src/mylinux/include/linux/sched.h : 1167행) 자료구조를 포인팅 init_task prev_task next_task … task_struct

sys_gettaskinfo() 라는 커널 정보를 사용자 모드에서 출력하는 새로운 314번 시스템 호출 구현 실습 3: getstat() sys_gettaskinfo() 라는 커널 정보를 사용자 모드에서 출력하는 새로운 314번 시스템 호출 구현 /* 시스템 호출 처리 함수 getstat.c */ $ vi /usr/src/mylinux/kernel/getstat.c #include <linux/unistd.h> #include <linux/errno.h> #include <linux/sched.h> #include <../arch/x86/include/asm/uaccess.h> #include "mystat.h" #include <linux/slab.h> #include <linux/file.h> asmlinkage int sys_getstat(int id, struct mystat *user_buf) { struct mystat *buf; int i = 0, cnt = 0; struct task_struct *search; search = &init_task; while(search->pid != id) search = list_entry((search)->tasks.next, struct task_struct, tasks); if(search->pid == init_task.pid) return(-1); } buf = kmalloc(sizeof(struct mystat), GFP_KERNEL); if(buf == NULL) buf->pid = search->pid; buf->ppid = search->parent->pid; buf->state = search->state; buf->priority = search->rt_priority; buf->policy = search->policy; buf->utime = search->utime; buf->stime = search->stime; buf->min_flt = search->min_flt; buf->maj_flt = search->maj_flt; copy_to_user((void *)user_buf, buf, sizeof(struct mystat)); return 0; /* 사용자 응용 test3.c */ #include <linux/unistd.h> #include <stdio.h> #include <errno.h> #include "mystat.h" #include <stdlib.h> struct mystat *mybuf; int i; int main(int argc, char* argv[]) { int task_number; if(argc != 2) printf("USAGE: a.out pid\n"); exit(1); } task_number = atoi(argv[1]); mybuf = (struct mystat *)malloc(sizeof(struct mystat)); if(mybuf == NULL) printf("Out of Memory\n"); printf("PID %d\n",task_number); i = syscall(__NR_getstat, task_number, mybuf); printf("%d\n", i); printf("PID = %d\n", mybuf->pid); printf("PPID = %d\n", mybuf->ppid); if(mybuf->state == -1) printf("Unrunable state\n"); else if(mybuf->state == 0) printf("Running state\n"); else if(mybuf->state == 1) printf("Interruptable state\n"); else if(mybuf->state == 2) printf("Uninterruptable state\n"); else if(mybuf->state == 4) printf(" Stopped state\n"); else if(mybuf->state == 8) printf(" Zombie state\n"); else if(mybuf->state == 16) printf("Dead state\n"); else printf("Unknown state\n"); printf("Priority = %d\n", mybuf->priority); printf("Policy = %d\n", mybuf->policy); printf("Task.utime = %lu\n", mybuf->utime); printf("Task.stime = %lu\n", mybuf->stime); printf("Task.starttime = %lu\n", mybuf->starttime); printf("minor fault = %lu\n", mybuf->min_flt); printf("major fault = %lu\n", mybuf->maj_flt); printf("opened files = %u\n", mybuf->open_files); return 0; /* 헤더 파일 mystat.h */ struct mystat { int pid; int ppid; /* * pid_t pid; * pid_t ppid; */ int state; int priority; int policy; long utime; long stime; long starttime; unsigned long min_flt; unsigned long maj_flt; int open_files; }; /* 새 커널 구성 않고 시스템 호출만 추가 */ $ make bzImage $ cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 $ reboot

커널 컴파일과 커널 교체 실습 2와 실습 3은 기존의 컴파일된 커널을 수정된 커널로 교체만 함 모듈 컴파일이 완료 된 상태에서 모듈 설정 없이 커널만 수정할 경우 모듈 컴파일은 하지 않고 커널 컴파일과 커널 교체 작업만 한다 # pwd /usr/src/mylinux ① # make bzImage 생성된 커널을 /boot 디렉토리에 복사 (새 커널 버전 생성 원하지 않으면 커널 이미지만 복사) ② # cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 (새 커널 버전 생성을 원하면) 또는 # make install (아래 작업 자동 수행하고 새 커널 버전 생성) [ $ cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 ] [ $ cp System.map /boot/System.map-3.2.37 (새 System.map으로 대치 ) ] 부트로더 설정 # vi /boot/grub/grub.cfg default=0 ③ # reboot 부팅시 F5로 커널 선택화면 전환 후 부트로드에서 새로 컴파일 한 커널 선택

실습실 부트로더 정리 os.sh 다른 수업 위해 실습실 부트로더 정리 /* os.sh */ #!/bin/sh sudo mount /dev/sda7 /mnt sudo cp /mnt/boot/grub/grub.cfg /boot/grub/grub.cfg sudo umount /mnt sudo grub-install /dev/sda # chmod +x os.sh # os.sh 내 커널 버전 로그인 위한 grub 구성 파일 생성 # update-grub /dev/sda

(Lab.2) Linux 커널에 시스템 호출 추가하기 실습 요약 (커널 소스 다운로드) # wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.37.tar.gz # tar xvfz linux-3.2.37.tar.gz # ln –s linux-3.2.37 mylinux (커널 수정 & 컴파일 & 설치 & 재부팅) ① # vi /usr/src/mylinux/arch/x86/include/asm/unistd_64.h 파일 수정  312번 __NR_newsyscall 추가 ② # vi /usr/include/x86_64-linux-gnu/asm/unistd_64.h 파일 수정 ③ # vi /usr/src/mylinux/arch/x86/kernel/syscall_table_32.S newsyscall() 등록 ④ # vi /usr/src/mylinux/include/linux/syscalls.h newsyscall() 등록 ⑤ # vi /usr/src/mylinux/kernel/newsyscall.c newsyscall() 처리 함수 코딩 ⑥ # vi /usr/src/mylinux/kernel/Makefile obj -y = 라인에 newsyscall.o 추가 ⑦ # cd /usr/src/mylinux (커널 소스의 상위 디렉토리로 이동) ⑧ # make mrproper (기존의 커널 설정 제거) ⑨ # cp ../linux-headers-3.2.0-29-generic/.config ./ ⑩ # make oldconfig (실행후 선택문 모두 엔터) ⑪ # make bzImage (컴파일, 새 커널 생성) ⑫ # make modules (모듈 컴파일) ⑬ # make modules_install (모듈 인스톨) ⑭ # make install (새 커널 설치) ⑮ # vi /boot/grub/grub.cfg default=0 첫 번 menuentry에 자기 이름 입력 ⑮+① # reboot (실습 결과 제출) ① Linux Kernel Compile Work Sheet 작성하여 제출 ② 사용자 수준 응용 코딩 & 컴파일 & 실행하여 결과 확인 화면 캡처하여 제출 /* 커널 코드 /usr/src/mylinux/kernel/newsyscall.c 작성*/ #include <linux/linkage.h> #include <linux/unistd.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/sched.h> asmlinkage int sys_newsyscall() { printk("Hello Linux, Student ID, Student Name is in Kernel\n"); return 0; } /*사용자 코드 test1.c 작성 */ #include <errno.h> #include <stdio.h> main() int i; i=syscall(__NR_newsyscall); printf(“%d\n”, i); $ gcc –o test1 test1.c 컴파일 $ ./test1 실행

(Lab.2) Linux 커널에 시스템 호출 추가하기 Work Sheet 학번 ( ) 이름 ( ) Linux Ubuntu Kernel linux-3.2.37 커널 프로그래밍 실습을 수행하면서 아래 각 물음에 답하세요. 시스템이 부팅될 때 부트 프로그램에 의해 구동되며 메모리에 상주하면서 시스템의 자원을 관리하며 사용자에게 서비스를 제공하는 운영체제의 핵심 부분을 무엇이라 하나요? 오늘 현재 시점에서 가장 최신의 안정한 (stable) 커널 버전은 무엇인가요? ( http://www.kernel.org/ ) 리눅스 파일 시스템의 어느 디렉토리 위치에서 커널 소스 코드를 다운로드 해야 하나요? 커널 항목들을 커널에 포함시킬지 모듈로 동작하게 할지 등을 설정 (configuration)을 하기 위해 실행해야 하는 명령은 무엇인가요? 새 시스템 호출의 명칭과 번호를 어느 파일에 새로 할당해 주어야 할까요? (두 개 파일의 전체경로로 답하세요) 시스템 호출을 수행하는 system_call() 함수가 실행될 때 참조하는 테이블로서 새 시스템 호출 함수를 등록해 줘야 하는 테이블은 무엇인가요? (전체경로로 답하세요) 커널 이미지 생성 (make bzImage)에 걸린 시간은 얼마나 되나요? 모듈 컴파일 (make modules)에 걸린 시간은 얼마나 되나요? 모듈 설치 (make modules_install)에 걸린 시간은 얼마나 되나요? 사용자 수준 응용 ./test1 실행 후 $ dmesg | tail 수행 결과로 화면에 출력된 내용을 무엇인가요?

(Lab.2) Linux 커널에 시스템 호출 추가하기 제출 방법 (숙제 화면 캡처하기) 재부팅후 그래픽 모드에서 시스템 호출 프로그램 test1.c test2.c test3.c를 실행한다 printk() 는 커널 모드로 출력하는 프로그램이기 때문에 유저 모드의 그래픽 화면에 아무런 내용이 출력되지 않는다 $ dmesg | tail -12 명령을 입력하여 시스템 메시지 끝부분을 출력한다 화면에 출력된 내용을 확인하고 키보드의 [Print Screen] 키를 눌러 화면을 캡쳐한다 파일이름을 영문(예, capture.png)으로 하여 저장한다 (Linux에 복사하기) capture.png가 위치한 디렉토리에서 $ ftp 117.16.244.171 Name: s자기학번 Passwd: ******* ftp> binary ftp> put capture.png ftp> bye (Linux에서 Windows로 파일 가져오기) Windows 명령 프롬프트 창에서 C:\>D: [Enter] D:\>ftp 117.16.244.59 User (117.16.244.59:(none)): 자기아이디 Password: ******* ftp> cd /home/os2013hwa (또는 b) ftp> ls ftp> get capture.png get capture.png? y

(참고) root 권한 획득 터미널에서 su root입력 암호 입력 cd /etc/pam.d vi gdm

(참고) root 권한 획득 gdm 파일을 열어 세번째 줄인 #auth    required pam_succeed_if.so user != root_quiet 라는 줄 앞에 #를 붙여 주석 처리 gdm: GNOME Display Manager pam_succeed_if.so: 인증 계정 테스트 quiet: 시스템 로그에 기록하지 않음

(참고) root 권한 획득 vi gdm-password 이 파일도 gdm 파일과 동일하게 3번째 줄인#auth    required pam_succeed_if.so user != root quiet 앞에 #를 붙여 주석 처리 logout 또는 reboot

(참고) 커널 수정 (1) 32비트 (Ubuntu 32비트) 커널 영역 시스템 호출 번호 할당 ① # vi /usr/src/mylinux/arch/x86/include/asm/unistd_32.h 파일 수정 __NR_newsyscall 349를 추가해준다 NR_syscalls로 시스템 호출의 총 개수를 써준다 예) __NR_newsyscall이 349 이면 NR_syscalls는 350 이다

(참고) 커널 수정 (2) 32비트 (Ubuntu 32비트) 유저 영역 시스템 호출 번호 할당 ② # vi /usr/include/i386-linux-gnu/asm/unistd_32.h 파일 수정 __NR_newsyscall 349를 추가해준다 NR_syscalls로 시스템 호출의 총 개수를 써준다 예) __NR_newsyscall이 349 이면 NR_syscalls는 350 이다

(참고) 커널 수정 (3) 시스템 호출 테이블 등록 (32비트 64비트 동일) 시스템 호출 처리 함수를 sys_call_table 테이블에 등록 ③ # vi /usr/src/mylinux/arch/x86/kernel/syscall_table_32.S 에 등록

(참고) 커널 수정 (4) 시스템 호출 함수 등록 (32비트 64비트 동일) ④ # vi /usr/src/mylinux/include/linux/syscalls.h 에 등록

커널 수정 (5) 시스템 호출 처리 함수 구현 일반 적으로 태스크 관리자 관련 함수는 /usr/src/mylinux/kernel/ 에 구현 파일 시스템 관련 함수는 /usr/src/mylinux/fs/ 밑에 구현 ⑤ # vi /usr/src/mylinux/kernel/newsyscall.c 코딩 /* 커널 코드 /usr/src/mylinux/kernel/newsyscall.c 코딩 */ #include <linux/linkage.h> #include <asm/uaccess.h> asmlinkage int sys_newsyscall() { printk("Hello Linux, 1234567 Sung MeeYoung is in Kernel\n"); /* write your name in English */ return 0; }

커널 수정 (6) ⑥ # vi /usr/src/mylinux/kernel/Makefile 수정 (32비트 64비트 동일) obj -y = 라인에 newsyscall.o 추가

커널 수정 (7~10) 커널 구성 ⑦ # cd /usr/src/mylinux (커널 소스의 상위 디렉토리로 이동) ⑧ # make mrproper (기존의 커널 설정 제거) 커널 버전 2.6부터 make dep 과 make clean 불필요 ⑨ # make menuconfig (범용적 커널 설정 스크립트 실행) 오류 나면 # yum –y install ncurses* 설치 옵션은 아래 사이트 참고 http://doc.kldp.org/KoreanDoc/html/Kernel24_Intro-KLDP/Kernel24_Intro-KLDP- 2.html (또는) # cp ../linux-headers-3.5.0-23-generic/.config ./ # make oldconfig (실행후 선택문 모두 엔터) 커널 컴파일 ⑩ # make bzImage (컴파일, 새 커널 생성)

커널 수정 (11~14) 모듈 컴파일 및 인스톨 모듈로 구성된 커널 내부 구성 요소를 알려주고, 이후 구성 요소들이 사용될 때 자동으로 커널에 적재되게 함 ⑪ # make modules (모듈 컴파일) ⑫ # make modules_install (모듈 인스톨) 새 커널을 /boot 디렉토리에 설치 ⑬ # make install (아래 작업 자동 수행) [ # cp arch/x86/boot/bzImage /boot/vmlinuz-3.2.37 ] [ # cp System.map /boot/System.map-3.2.37 (새 System.map으로 대치 ) ] Install한 커널로 들어가기 ⑭ # reboot 재부팅 후 grub 선택 메뉴에서 3번째 previous Linux 선택 후 linux-3.2.37 선택 실습 1: newsyscall() 사용자 수준 응용 코딩 & 컴파일 & 실행하여 결과 확인

System Administration Reset root password Launch the GRUB boot loader Select the kernel Press the e key to edit the entry Select second line (the line starting with the word kernel) Press the e key to edit kernel entry so that you can append single user mode Append the letter S (or word Single) to the end of the (kernel) line Press ENTER key Now press the b key to boot the Linux kernel into single user mode At prompt type passwd command to reset password: # passwd root # passwd –d root (Ref.) http://www.cyberciti.biz/faq/linux-reset-forgotten-root-password/ Linux 설치