Presentation is loading. Please wait.

Presentation is loading. Please wait.

2015 OS Linux Kernel Programming

Similar presentations


Presentation on theme: "2015 OS Linux Kernel Programming"— Presentation transcript:

1 2015 OS Linux Kernel Programming

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

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

4 시스템 호출 추가 과정 Hanbit Media(c)

5 커널 빌드 (컴파일) 과정 # make 또는 # make all make install

6 커널 컴파일 (참고) /usr/src/linux 위치 # 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

7 (참고) 부트 로더 보수 내 커널 버전 로그인 위한 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

8 나만의 시스템 호출 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 코딩 매우 중요!

9 나만의 시스템 호출 newsyscall (351)
/*커널 /usr/src/linux /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

10 나만의 시스템 호출 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);

11 나만의 시스템 호출 getcpuinfo (353)
/* /usr/src/linux-3.13/arch/x86/include/asm/processor.h */ struct cpuinfo_x86 { __u x86; /* CPU family */ __u x86_vendor; /* CPU vendor */ __u x86_model; __u 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 __u x86_virt_bits; __u x86_phys_bits; /* CPUID returned core id bits: */ __u x86_coreid_bits; /* Max extended CPUID function supported: */ __u extended_cpuid_level; /* Maximum supported CPUID level, -1=no CPUID: */ int cpuid_level; __u 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: */ u x86_max_cores; u apicid; u initial_apicid; u x86_clflush_size; /* number of cores as seen by the OS: */ u booted_cores; /* Physical processor id: */ u phys_proc_id; /* Core id: */ u cpu_core_id; /* Compute unit id */ u compute_unit_id; /* Index into per_cpu list: */ u 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

12 /* 커널 코드 /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; }

13 나만의 시스템 호출 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; };

14 /* 커널 코드 /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;

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

16 시스템 호출 과정 /* /*/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() 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

17 (참고) 리눅스 방화벽 관리 방화벽 정지 방화벽 시작
# /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

18 (참고) Linux Virtual Machine 설치하기
➜ 방문하여 숙독 ➜ Virtual Box 다운로드 및 설치 ➜ 파일 다운로드 및 실행 후 불러오기 제어판에서 호스트 컴퓨터 사양 확인 후 , 테스트 원하는 코어 개수, 메모리 설정(실제 메모리 보다는 작아야 함) ➜ 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) 로그인


Download ppt "2015 OS Linux Kernel Programming"

Similar presentations


Ads by Google