레이블이 Linux인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Linux인 게시물을 표시합니다. 모든 게시물 표시

2014년 12월 12일 금요일

Copy On Write Page (COW)

Linux의 vfork라는 system call은 fork의 복사하는 비효율성 때문에 나온것이다.
fork 다음에 바로 exec* 를 호출하는 경우에 대신 씀..
vfork는 부모의 메모리영역을 복사하지 않고 공유..
- 자식 프로세스가 exit나 exec를 호출할 때까지 부모 프로세스는 실행되지 않고 기다린다.

- 현재는 fork의 효율성이 좋아져, vfork를 쓸필요가 없다..
현대 운영체제(UNIX, Linux, Mac OS X)의 fork() 구현 방식
 → "Copy-On-Write(page)" mechanism  "COW"


COW는 윈도우도 마찬가지.. 그림판 창을 3개 띄운다면.. 메모리를 3배  잡아먹고 있는게 아니다. 첫번째 창 메모리와 동일한 영역을 가리키고 있다가. 특정 창에서 그림을 그리면 그때 특정영역의 메모리 복사본을 생성한다. 

Linux 파일 데이터 입출력

systemcall --> c표준라이브러리 --> 윈도우
open() --> fopen()   --> CreateFile()
close() --> fclose()  --> CloseHandle()
read()  --> fread()   --> ReadFile()
write() --> fwrite()  --> WriteFile()
lseek() --> fseek()   --> SetFilePointer()
---------------
dup(),dup2()             --> DuplicateHandle()
ioctl() --> 하드웨어 장치제어 --> DeviceIoControl()
fcntl() --> 파일 컨트롤기능

Linux 라이브러리 제작 및 사용

■ 정적(static) 라이브러리 : *.a -->*.lib
a.c --> a.o + 라이브러리코드(링크할때 합쳐짐) --> a.out
b.c --> b.o + 라이브러리코드(링크할때 합쳐짐) --> b.out
 : 같은 코드들이 들어있음으로 스토리지(임베디드는 롬)를 많이 차지함.
 : 마찬가지로 실행시 램도 많이 차지함.
 : 라이브러리가 수정 필요할 경우 모두 다시 링크해야함.
 : 호출하는 코드의 위치가 이미 결정 되어있음으로.. 다이렉트 호출.. 속도가 아주약간 빠르다.
 : 단독실행 가능

▷ 정적 라이브러리 제작
ex) ar rsv libcalc.a addsub.o muldiv.o
r replace .o파일이 있으면 대체
s speed 링크 속도를 빠르게 하는 옵션.(검색정보추가)
v verbose


▷ 정적라이브러리 사용
ex) gcc -o calctest calctest.o -lcalc -L ./
-L 옵션 라이버리 경로 지정

■ 공유(shared) 라이브러리 : *.so -->*.dll
a.c --> a.o + 라이브러리 정보 --> a.out
                                       + 라이브러리 코드 (실행시점에)
b.c --> b.o + 라이브러리 정보 --> b.out


▷ 리눅스 공유 라이브러리관련 파일 종류
아래에서 31은 가리키는 경로의 글자 수 -> 심볼릭 링크
lrwxrwxrwx 1 root root    31 Dec  7  2013 libguilereadline-v-17.so -> libguilereadline-v-17.so.17.0.3
lrwxrwxrwx 1 root root    31 Dec  7  2013 libguilereadline-v-17.so.17 -> libguilereadline-v-17.so.17.0.3
-rw-r--r-- 1 root root 13856 Aug 26  2011 libguilereadline-v-17.so.17.0.3

libreadline.so : 링크할때 사용된다. (개발용)
ex) gcc -o someprog someprog.c -lreadline
gcc로 somprog.c 를 컴파일해서 someprog 실행 프로그램을 만들때 -libreadline.so을 링크해서 만들어라.

.5는 메이저 버전넘버
libreadline.so.5 : 실행 파일 내부에 저장되는 이름으로, 프로그램을 실행할 때 사용된다. (실행용)
ex) ./somprog   프로그램 실행시 내부에서 사용
 -> 리눅스는 라이브러리에 버전넘버를 가지고 있어, 라이브러리의 버전이 공전할 수 있다.
 -> 버그 패치가 쉽다.

.2는 마이너 버전넘버
libreadline.so.5.2 : 실제 라이브러리 코드를 담고 있다.(실행용)


ex) arm-none-linux-gnueabi-gcc -march=armv4t -fPIC -c addsub.c muldiv.c
PIC = Position Independent Code
-> 동적 라이브러리를 할때 필수 옵션
 -> 여러 프로그램이 공유 라이브러리를 메모리상에 올린다고 가정, 라이브러리의 주소가 다를것임.


gcc  -march=armv4t -shared -Wl,-soname=libcalc.so.1 -o libcalc.so.1.0 addsub.o muldiv.o
공유 라이브러리를 만드는 명령

ldconfig -n .
lib파일의 심볼링 링크를 생성하는 명령(실행용)

ln -s libcalc.so.1 ./libcalc.so
심볼릭 링크를 매뉴얼로 생성 (개발용)

gcc -march=armv4t -o calctest calctest.o -lcalc -L.
calctest.o 오브젝트 파일로 caltest실행파일을 만들때 libcalc 라이브러리 파일을 현재경로에서 찾아서 만들어라.
공유라이브러리나 정적라이브러리나 만드는 것은 똑같다..

※참고1 : 정적라이브러리, 공유라이브러리가 둘다 있다면 링크 우선순위는 공유라이브러리.. 윈도우랑 같음..

※참고2 : export LD_LIBLARY_PATH=/tftpboot/libtest
lib 검색 경로 환경변수 지정


※참고3 : ldd 실행파일
실행파일이 쓰고 있는 공유라이브러리목록 조회

※참고4 : 심볼링 링크.. 복사..
cp libcalc.so.1 /usr/lib  심볼릭 링크를 복사를 하는거면 -a 옵션을 추가해야함.
아니면 내용이 원본과 동일..

Linux gcc가 실행시키는 프로그램

1. cpp 전처리기 -----> 전처리된 파일  *.i
2. cc1 컴파일러 -----> 어셈블리어 파일 *.s
3. as 어셈블러 ------> 오브젝트파일 *.o
4. ld 링커  ---------> 링크후 실행파일 a.out

Linux 시스템 필수 구성요소

Bootloader + Linux kernel + Libraries + Applications
 -> Embeded Linux로 필요한것만 해서 최소로 줄인다면.. 2MB까지 줄일수도..

Linux gcc 옵션

-g 옵션
소스레벨에서 디버그를 한다면..
소스코드 - 기계어 간의 매칭 되는 정보가 있어야 함으로
gcc -g 옵션하면 out파일의 크기는 커진다.

-o(소문자o) 옵션
out 파일의 경로를 지정

-O (대문자 O) 옵션
gcc hello.c   -> gcc hello.c -O0
gcc hello.c -O1 -> gcc hello.c -O   1단계 최적화, 레벨별 성능향상의 비율이 가장큼
-O2
-O3
-Os  : size 최적화. 다른것은 속도..소형 Embeded라면.. 필요할 수 있음..
개발 단계에서는 최적화 하지 않고 디버깅을 위해 -g옵션을
어떤 옵션을 써야 할까.. 리눅스 운영체제의 컴파일 옵션을 본다면.. O2, 사이즈가 중요하다면 Os

-std 옵션
내가 작성한 소스코드가 표준을 따르고 있는지 워닝을 보기 원한다면
gcc -std=c90(ansi표준) 처럼 입력함.
지금의 gcc는 표준에 일치하지 않더라도 워닝을 띄우지 않음으로
필요하다면 - pedantic 옵션과 같이 사용
pedantic의 의미는 "지나치게 룰을 따지는?"정도..
-std=c90은 -ansi 와 동일함.
내 코드가 ansi 표준에 맞게 작성했는지 확인해야한다면
gcc -ansi -pedantic 옵션을 추가하면된다.

-W 옵션 워닝을 보여줌
-Wall 모든 경고를 보여줌.(내가 작성한 것중에서)

-D 옵션 컴파일시 define함..#define
gcc 옵션으로 -D를 한다는것은 소스코드 레벨에서 맨 위쪽에서 define하는것과 같음.

-m 옵션
cpu마다 달라지는 옵션, Embeded 프로그램 해야할때 자주 사용
x86
ARM
MIPS
PowerPC
gcc는 여러 종류의 cpu를 지원하지만..기본 상태에서는 하나의 cpu만 지원..
우분투에서는 x86 cpu만 되지만..
gcc를 ARM용을 받아다가 gcc > cpu이름 -gcc 로 재컴파일 하게 되면
ARM용 gcc를 만들어서 쓸수 있음..Cross Compiler
현재 하드웨어에 맞게 어셈코드를 생성해야함.
arm 아키텍쳐
ARMv4
ARMv5
ARMv6
ARMv7 (요즘 많이 쓰이는 핸드폰)
ARMv8
-march=armv4t 처럼 아키텍쳐를 지정하거나
또는 cpu를 안다면 cpu를 직접 지정 -mcpu=arm920t
적용할 보드가 big-endian을 쓴다면 -mbig-endian 옵션으로 수정해주어야함.


./ 상대경로 현재 경로
../ 상대경로 현재의 상위 경로
gcc -c *.c -I ../include/
-I 옵션 인클루드파일을 이 경로에서도 찾으라는 명령


라이브러리 사용
gcc ... -l 라이브러리명
gcc ... -l 라이브러리파일명
ex) gcc -lm libm.so 또는 libm.a 둘중 하나를 찾아서 링크
둘다 있을 경우 공유 라이브러리가 우선
정적 라이브러리를 쓰고 싶을 경우 -static 옵션을 씀.
Embeded 시스템에서는 왠만하면 동적으로.


gcc -Wa,옵션1,옵션2,..... 어셈블러에게 전달  -Wl,옵션1,..링커에게 전달..
전처리기 : gcc에 완벽하게 포함
컴파일러 : gcc에 완벽하게 포함
어셈블러 : 아래 두개는 gcc에 완벽히 포함되지 않음. 어셈블러,링커 매뉴얼을 확인해야함.gcc에 없음.
링커


gcc에서 옵션순서 상관..
-다른것은 괜찬으나 library 관련 -l 옵션은 순서 상관있음.뒤에 넣어야함.


gcc -M *.c
-M 옵션 헤더파일의 의존성 표준헤더까지 싹
-MM 옵션 개발자가 만든것만


gcc -pg -g pgtest2.c
-pg 옵션 : 실행시 프로그램 정보확인 옵션

※참고 : gprof -A a.out > data.txt
-pg 옵션으로 생성된 파일을 분석하는 tool
 --> arm보드환경에서는 arm용 gprof를 따로 사용

※참고 : 컴파일 할때는 컴파일만, 컴파일 후 링크하는게 좋다.
프로젝트가 커지면 컴파일시간이 오래 걸림..