2015 OS Linux Kernel Programming

Slides:



Advertisements
Similar presentations
Apr. 25, 2013 Laboratory of Systems Medicine BASIC LINUX COMMANDS.
Advertisements

1 장 Unix/Linux 소개 1 Helpers. 1 장 내용 1. 왜 유닉스인가 ? 2. 유닉스 시스템 구조 3. 유닉스 역사 및 버전 4. 리눅스 설치 ( 별도 2 시간 실습 ) 5. 사용 환경 6. 사용자 계정 관리 Unix/Linux 2.
Basic of Buffer Over Flow
SYSTEM CALL (Syscall) CSLAB SEWON PARK.
Linux/UNIX Programming APUE (The Environment of a UNIX Process)
EZ Board-M In-Ho, Roh Real Time System Lab.
Ubuntu 실습 환경 만들기 컴퓨터공학부 김찬민.
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
Chapter 6. 리눅스 백도어 황 선 환.
Cross Compiler를이용한 커널 컴파일 및 포팅
MYSQL 설치.
MYSQL 설치 및 설정 아이티즌 기술연구소 김태성 연구원
Kernel Programming Kernel
커널 컴파일 및 개발 환경 구축 IT EXPERT 리눅스 커널 프로그래밍 Author : Byungki Kim
Hadoop 2.완전 분산 처리.
System Call Linux Kernel 수업 3번째.
Linux/UNIX Programming
FUSING.
디바이스 드라이버.
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
Department of Computer Engineering
Module Programming Linux Kernel 수업 4번째.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
목차 커널의 개념 및 기능 커널 포팅 램디스크.
6 프로세스 생성과 실행.
Team Project : SSL 2008/05/27 정보보호 응용 발표자 : 신용철.
임베디드 리눅스 설치 및 동작 Lecture #5.
Mysql Install on Azure
System Call 구현 기초 (since 2004) (교재에는 7th 2006에 포함)
임베디드 시스템 개론 크로스 플랫폼 설치 2일차 강의 자료 Embedded System Lab.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
Department of Computer Engineering
강 명 수 LINUX 설치 강 명 수
Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)
Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)
Root Filesystem Porting
링크 파일 생성[1] 링크 하드링크 생성 : link(2) 이미 있는 파일이나 디렉토리에 접근할 수 있는 새로운 이름
Term Project Team Member
Operating System 5주차 - System Call Analysis -
Root Filesystem Porting
Homework 6… 12월 2일(금) 11:59pm까지 자신의 이름과 학번을 출력해 주는 유닉스/리눅스 네트워크 소켓 서버 프로그램 과 클라이언트 프로그램 을 작성해 보세요 참고 (실습1) Hello 프로그램 helloserver.c helloclient.c 컴파일.
WinCE Device Driver 실습 #2
커널 모듈 프로그래밍 (Kernel Module Programming)
Cross Compiler 설치.
System Call 구현 기초 Linux 커널의 새로운 시스템 호출 구현은 아래 두 가지 작업으로 구성 커널 수정
실시간 자원 량 정보 제공을 결합한 Heartbeat
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
5 프로세스 정보.
Cross Compiler를이용한 커널 컴파일 및 포팅
문자 디바이스 드라이버 임베디드 시스템.
Linux Kernel Programming newsyscall (since 2004~ textbook 7th 2006~)
Device Driver 임베디드 시스템 I.
Windows에서 Virtual Box를 이용한 Ubuntu 설치
영상처리 실습 인공지능연구실.
Kernel Programming Environment
임베디드 시스템 개론 임베디드 타겟 보드 포팅 및 H/W 제어 3일차 강의 자료 Embedded System Lab.
Stepper Motor 디바이스 드라이버
리눅스 커널 프로그래밍 환경 구축 IT EXPERT 리눅스 커널 프로그래밍 Author : Byungki Kim
Department of Computer Engineering
네트워크 환경 구축과 이미지 전송 호스트/타겟 통신 직렬 통신을 이용한 이미지 전송 수퍼 데몬 BOOTP 환경 구축
Kernel, Ramdisk, JFFS2 Porting
Kernel Programming Kernel
Execution with Unnecessary Privileges
GDB - GNU Debugger 김진용.
시스템 인터페이스 Lab1 X-window 및 명령어 사용.
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
argc, argv 의 사용방법 #include <stdio.h>
Kernel Porting Lecture #7.
C.
Presentation transcript:

2015 OS Linux Kernel Programming

주의 사항 임베디드 수업 자료 백업 필수 반드시 Operating System으로 부팅 네트워크 연결 필수 루트 권한 획득 $ su unixlinux 그래픽 드라이버 삭제 # apt-get remove nvidia-304

커널 소스 다운로드 ※ 모든 작업은 “super user (root)” 권한으로 수행해야 합니다! $ su [Enter] (입력: unixlinux) 또는 $ sudo su 커널을 수정하기 위해서는 커널 소스 필요 # cd /usr/src 디렉토리로 이동 커널 다운로드 Application ➜ Internet ➜ Iceweasel 실행하여 https://www.kernel.org 에서 최신 커널 linux-3.19.1.tar.gz 다운로드 Places ➜ Downloads의 커널을 /usr/src/로 복사 다운 받은 커널을 압축해제 # tar xvfz linux-3.19.1.tar.gz

시스템 호출 추가 과정 2019-06-30 Hanbit Media(c)

커널 빌드 (컴파일) 과정 # make 또는 # make all 2019-06-30 make install

커널 컴파일 (참고) https://www.debian.org/releases/lenny/sparc/ch08s06.html.ko /usr/src/linux-3.19.1 위치 # make mrproper # make menuconfig  exit  save 오류 나면 libncurses5-dev 설치 # apt-get install libncurses5-dev # make # make modules_install (커널 이미지 확인) # ls –l arch/x86/boot (커널 모듈 확인) # ls –l /lib/modules # make install /* 커널 이미지 설치 */ # vi /boot/grub/grub.cfg /* title 편집 */ # reboot # uname -a

(참고) 부트 로더 보수 내 커널 버전 로그인 위한 grub 구성 파일 생성 (SCSI disk) # update-grub /dev/sda 또는 # grub-install /dev/sda (IDE disk) # update-grub /dev/hda 또는 # grub-install /dev/hda 다른 수업 위해 실습실 부트 로더 정리 /* os.sh */ #!/bin/sh sudo mount /dev/sda4 /mnt sudo cp /mnt/boot/grub/grub.cfg /boot/grub/grub.cfg sudo umount /mnt sudo grub-install /dev/sda4 # chmod +x os.sh # os.sh 하드디스크 파티션 정보 $ fdisk –l $ sudo fdisk –l $ lsblk http://www.cyberciti.biz/

나만의 시스템 호출 newsyscall (351) (32-bit) $ cd /usr/src/linux-3.13 # vi /usr/include/i386-linux-gnu/asm/unistd_32.h #define __NR_newsyscall 351 # vi /usr/src/linux-3.13/arch/x86/syscalls/syscall_32.tbl 359 i386 newsyscall sys_newsyscall # vi /usr/src/linux-3.13/include/linux/syscalls.h asmlinkage long sys_newsyscall( void ); # vi /usr/src/linux-3.13/kernel/newsyscall.c 코딩 # vi /usr/src/linux-3.13/kernel/Makefile obj -y = 라인 마지막에 newsyscall.o 추가 # cd /usr/src/linux-3.13 # make mrproper # make menuconfig  exit  save 오류 나면 libncurses5-dev 설치 # apt-get install libncurses5-dev # make # make modules_install (커널 이미지 확인) # ls –l arch/x86/boot (커널 모듈 확인) # ls –l /lib/modules # make install /* 커널 이미지 설치 */ # vi /boot/grub/grub.cfg /* title 편집 */ # reboot argument type void 코딩 매우 중요!

나만의 시스템 호출 newsyscall (351) /*커널 /usr/src/linux-3.19.1/kernel/newsyscall.c*/ #include <linux/linkage.h> #include <linux/kernel.h> asmlinkage int sys_newsyscall( void ) { printk("Hello Linux Kernel by MYSung\n"); return 0; } /*사용자 수준 응용 프로그램 test1.c*/ #include <linux/unistd.h> #include <stdio.h> main(void) { int i; i=syscall(__NR_newsyscall); printf("__NR_newsyscall = %d\n", __NR_newsyscall); printf("syscall return value = %d\n", i); return 0; } $ gcc test1.c –o test1 $ ./test1 $ dmesg | tail

나만의 시스템 호출 newsysadd (352) (32-bit) $ cd /usr/src/linux-3.13 # vi /usr/include/i386-linux-gnu/asm/unistd_32.h #define __NR_newsysadd 352 # vi /usr/src/linux-3.13/arch/x86/syscalls/syscall_32.tbl 352 i386 newsysadd sys_newsysadd # vi /usr/src/linux-3.13/include/linux/syscalls.h asmlinkage long sys_newsysadd(int a, int b, int *to_user); # vi /usr/src/linux-3.13/kernel/newsysadd.c /* 커널 코드 /usr/src/mylinux/kernel/newsysadd.c 코딩*/ # vi /usr/src/linux-3.13/kernel/Makefile obj -y = 라인 마지막에 newsysadd.o 추가 # cd /usr/src/linux-3.13 # make bzImage # cp arch/x86/boot/bzImage /boot/vmlinuz-3.13 # vi /boot/grub/grub.cfg 부트로더 검토 # reboot $ gcc test2.c –o test2 $ ./test2 $ dmesg | tail /*커널 코드 /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); printf("__NR_newsysadd = %d\n", __NR_newsysadd);

나만의 시스템 호출 getcpuinfo (353) /* /usr/src/linux-3.13/arch/x86/include/asm/processor.h */ struct cpuinfo_x86 { __u8 x86; /* CPU family */ __u8 x86_vendor; /* CPU vendor */ __u8 x86_model; __u8 x86_mask; #ifdef CONFIG_X86_32 char wp_works_ok; /* It doesn't on 386's */ /* Problems on some 486Dx4's and old 386's: */ char rfu; char pad0; char pad1; #else /* Number of 4K pages in DTLB/ITLB combined(in pages): */ int x86_tlbsize; #endif __u8 x86_virt_bits; __u8 x86_phys_bits; /* CPUID returned core id bits: */ __u8 x86_coreid_bits; /* Max extended CPUID function supported: */ __u32 extended_cpuid_level; /* Maximum supported CPUID level, -1=no CPUID: */ int cpuid_level; __u32 x86_capability[NCAPINTS+NBUGINTS]; char x86_vendor_id[16]; char x86_model_id[64]; /* in KB - valid for CPUS which support this call: */ int x86_cache_size; int x86_cache_alignment; /* In bytes */ int x86_power; unsigned long loops_per_jiffy; /* cpuid returned max cores value: */ u16 x86_max_cores; u16 apicid; u16 initial_apicid; u16 x86_clflush_size; /* number of cores as seen by the OS: */ u16 booted_cores; /* Physical processor id: */ u16 phys_proc_id; /* Core id: */ u16 cpu_core_id; /* Compute unit id */ u8 compute_unit_id; /* Index into per_cpu list: */ u16 cpu_index; u32 microcode; }; (32-bit) $ cd /usr/src/ulinux-3.13 # vi /usr/include/i386-linux-gnu/asm/unistd_32.h #define __NR_getcpuinfo 353 # vi /usr/src/linux-3.13/arch/x86/syscalls/syscall_32.tbl 353 i386 getcpuinfo sys_getcpuinfo # vi /usr/src/linux-3.13/include/linux/syscalls.h asmlinkage void sys_getcpuinfo(struct cpu_info *info); # vi /usr/src/linux-3.13/kernel/getcpuinfo.c /* 커널 코드 /usr/src/mylinux/kernel/getcpuinfo.c 코딩*/ # vi /usr/src/linux-3.13/kernel/Makefile obj -y = 라인 마지막에 getcpuinfo.o 추가 # cd /usr/src/linux-3.13 # make bzImage # cp arch/x86/boot/bzImage /boot/vmlinuz-3.13 # vi /boot/grub/grub.cfg 부트로더 검토 # reboot $ gcc test3.c –o test3 $ ./test3 $ dmesg | tail $ cat /proc/cpuinfo 커널에 항상 struct cpuinfo_x86 데이터를 유지하고 있음 /usr/src/linux-3.19/arch/x86/include/asm/processor.h (참고) $ cat /proc/cpuinfo /usr/src/linux-3.19/arch/x86/kernel/cpu/proc.c

/* 커널 코드 /usr/src/mylinux/kernel/getcpuinfo.c*/ #include <linux/kernel.h> #include <asm/processor.h> #include <asm/uaccess.h> struct cpu_info { char vendor_id[16]; char model_id[64]; int cache_size; }; asmlinkage int sys_getcpuinfo(struct cpu_info *info) { struct cpu_info src; sprintf(src.vendor_id, "%s", boot_cpu_data.x86_vendor_id); sprintf(src.model_id, "%s", boot_cpu_data.x86_model_id); src.cache_size = boot_cpu_data.x86_cache_size; copy_to_user(info, &src, sizeof(struct cpu_info)); } /*사용자 수준 응용 프로그램 test3.c*/ #include <linux/unistd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> struct cpu_info { char vendor_id[16]; char model_id[64]; int cache_size; }; int main(int argc, char* argv[]) { int i; struct cpu_info info; i = syscall(__NR_getcpuinfo, &info); printf("Vendor id: %s\n", info.vendor_id); printf("Model id: %s\n", info.model_id); printf("Cache size in KB: %d\n", info.cache_size); return 0; }

나만의 시스템 호출 getstat (354) /* 헤더 파일 mystat.h */ struct mystat { int pid; (32-bit) $ cd /usr/src/ulinux-3.13 # vi /usr/include/i386-linux-gnu/asm/unistd_32.h #define __NR_getstat 354 # vi /usr/src/linux-3.13/arch/x86/syscalls/syscall_32.tbl 354 i386 getstat sys_getstat # vi /usr/src/linux-3.13/include/linux/syscalls.h asmlinkage long sys_getstat(int id, struct mystat *user_buf); # vi /usr/src/linux-3.13/kernel/getstat.c /* 커널 코드 /usr/src/mylinux/kernel/getstat.c 코딩*/ # vi /usr/src/linux-3.13/kernel/Makefile obj -y = 라인 마지막에 getstat.o 추가 # cd /usr/src/linux-3.13 # make bzImage # cp arch/x86/boot/bzImage /boot/vmlinuz-3.13 # vi /boot/grub/grub.cfg 부트로더 검토 # reboot $ vi mystat.h gcc test4.c –o test4 $ ./test4 $ dmesg | tail /* 헤더 파일 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; };

/* 커널 코드 /usr/src/mylinux/kernel/getstat.c 코딩*/ /* 사용자 수준 응용 프로그램 test4.c */ #include <linux/unistd.h> #include <stdio.h> #include <errno.h> #include "mystat.h" #include <stdlib.h> struct mystat *mybuf; int main(int argc, char* argv[]) { int task_number, i; 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("__NR_getstat=%d, return value=%d\n", __NR_getstat, 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; /* 커널 코드 /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; 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(user_buf, buf, sizeof(struct mystat)); return 0;

태스크 리스트 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

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

(참고) 리눅스 방화벽 관리 방화벽 정지 방화벽 시작 # /sbin/service iptables stop 또는 # /etc/init.d/iptables stop 21번 (ftp) 포트 개방 # iptables -I INPUT 1 -p tcp --dport  21  -j ACCEPT /*I(아이)*/ # iptables -I OUTPUT 1 -p tcp -–dport  21  -j ACCEPT /*I(아이)*/ 22번 (ssh) 포트 개방 # iptables -I INPUT 1 -p tcp --dport  22  -j ACCEPT /*I(아이)*/ # iptables -I OUTPUT 1 -p tcp -–dport  22  -j ACCEPT /*I(아이)*/ 23번 (telnet) 포트 개방 # iptables -I INPUT 1 -p tcp --dport  23  -j ACCEPT /*I(아이)*/ # iptables -I OUTPUT 1 -p tcp --dport  23  -j ACCEPT /*I(아이)*/ 방화벽 시작 # /sbin/service iptables start 또는 # /etc/init.d/iptables start

(참고) Linux Virtual Machine 설치하기 http://people.westminstercollege.edu/faculty/ggagne/osc/vm/ ➜ 방문하여 숙독 http://download.virtualbox.org/virtualbox/4.3.28/VirtualBox-4.3.28-100309-Win.exe ➜ Virtual Box 다운로드 및 설치 http://people.westminstercollege.edu/faculty/ggagne/osc/vm/OS-Concepts.ova ➜ 파일 다운로드 및 실행 후 불러오기 제어판에서 호스트 컴퓨터 사양 확인 후 , 테스트 원하는 코어 개수, 메모리 설정(실제 메모리 보다는 작아야 함) ➜ power on id: os (passwd: os) 로그인 $ su passwd: cmpt351 # vi /etc/pam.d/gdm3 #auth required pam_succeed_if.so user != root quiet_success (# 코멘트로 무력화) 로그아웃 id: root (passwd: cmpt351) 로그인