리눅스 유저 추가 한달에 한번은 쓰는 것같은데 맨날 옵션을 까먹는다..


useradd [유저네임] -m -s /bin/sh

m은 홈디렉토리를 만들어누는거고 s는 기본 쉘 설정을 의미


비밀번호 변경은 passwd [유저네임]


파일압축은(.tar.gz)

tar -zcvf [파일명] [압축할거]


압축해제는(.tar.gz)

tar -zxvf [압축풀거]

블로그 이미지

powerprove

,

리눅스 공유라이브러리를 간단하게 만들어보자


코드는 간단하게 만들어본다.




명령어는 gcc -fPIC -shared -o Jlibc.so Jlibc.c




라이브러리를 만들었다.


이제 한번 적용시켜보자

새로운 C코드를 만든다.


여기서 컴파일할때 공유라이브러리 설정을 해줘야하는데

환경변수에 공유라이브러리 경로를 추가해줘야한다.

export를 이용해서 환경변수를 바꿀수 있고

env를 이용해서 확인할수 있다.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:경로(기존에 있던 라이브러리를 추가함.)


이제 a.c를 컴파일 해보자


컴파일은 gcc -o a a.c -w -L -l 라이브러리 이름

성공적으로 만들었다.!

'system > level1' 카테고리의 다른 글

리눅스 유저 추가  (0) 2017.05.11
컴파일 과정(LINUX GCC)  (0) 2017.04.10
linux 정적 컴파일 동적 컴파일  (0) 2017.04.09
리눅스 파일 권한 설정  (0) 2017.04.09
리눅스 기초(8086 메모리 구조)  (0) 2017.04.06
블로그 이미지

powerprove

,

컴파일이란


C같은 고오옹오오오오급 언어를 기계어로 바꿔줘서 컴퓨터가 실행할 수 있도록 해준다.


우리가 흔히 이야기 하는 컴파일 과정은 

전처리 -> 컴파일 -> 어셈블러 -> 링커 과정을 거친다.


전처리기


전처리기 부분을 살펴보자

전처리기 과정은 주석을 제거하고 define 등을 치환하고 헤더파일을 삽입해준다.


gcc에서는 다음과 같이 볼 수 있다.


이렇게 소스 파일을 만들고 전처리기 과정을 거쳐 보겠다.

컴파일은

gcc -E -o [파일명].i [파일소스].c

하면된다. 


전처리기를 처음 열어보면 뭔가 많이 있다..

전처리기의 역할중 하나인 헤더파일 삽입인데 처음 소스에 #include <stdio.h>가 있다.

때문에 전처리기는 우선 디렉토리를 검색해 stdio.h를 찾는다.

그리고 stdio.h안에도 헤더파일이 삽입되어있을텐데 그럴경우 다시 디렉토리를 검사해 그 헤더파일을 삽입한 후에 나머지 stdio.h을 삽입한다.

마지막 부분에 내려가면 우리의 main소스가 있을것이다.


우선, 주석이 사라진것을 볼수 있다. 

그리고 #define mineral 50으로 설정해주고 printf 2번째 인자에 mineral이라고 적었었는데 50으로 치환되어 있는 사실을 확인 할 수 있다.


컴파일


컴파일 과정은 간단하게 어셈코드로 변환하는 작업이다.

컴파일은 전단부 중단부 후단부 셋으로 나눠서 작업이 된다.


각각의 역할을 간단하게 말하다면, 

전단부의 역할은 소스코드에서 에러가 있는지 체크한다.

중단부의 역할은 아키텍처와 상관없는 최적화를 시키는 것이다.(SSA를 기반으로 최적화)

후단부의 역할은 해당 아키텍처와 관련있는 최적화를 시킨다.  그리고 어셈블리어로 변환 시켜준다.

아키텍처는 (i386, arm, amd64 등이 있다. )


gcc 로 컴파일 이후를 볼라면

gcc -S -o [파일명].s [파일소스].c

를 입력하면 된다.


짠 우리가 보기 편한 어셈블리어 코드로 보여주는 것을 확인 할 수 있었다.

컴파일 과정에서는 에러 검사도 한다고 했다.

그렇다면 에러 있는 소스는 전처리기 과정이 될까?

확인하기 위해 일부로 에러있는 코드를 만들어 보았다.

보면 printf첫번째에 세미콜론(;)이빠져있는 것을 확인 할 수 있다.

그럼 이제 컴파일 해보자


전처리기 과정은 성공하지만 컴파일 과정에서 에러를 표출해주는 것을 확인할 수 있었다.


어셈블러


어셈블러는 오브젝트 파일을 만들어 준다.(기계어) 오브젝트 파일은 ELF의 구조를 가진다.

쉽게 설명하면 코드영역은 코드영역, bss 등등으로 나누어준다.


컴파일은

gcc -c -o [파일명].o [소스 파일명].c


링커


링킹과정은 어셈블러를 거친 오브젝트 파일들과 라이브러리들을 링크시키고 실행가능한 실행 파일이 만들어진다.


gcc -o [파일이름] [파일 소스명].c



오브젝트파일과 실행파일의 차이점


오브젝트파일과 실행파일 둘다 ELF구조를 가지는데 왜 실행파일만 실행이 되는지 의문이였고

둘의 관계가 시스템 처음 공부할 때는 어려웠었다.


둘의 가장 큰 차이점은 오브젝트파일에는 주소 정보가 확실하지 않다.

말로하는것보다 보는게 더 편하기 때문에

readelf -S(segment 확인)을 통해서 비교해보자


오브젝트 파일의 세그먼트


실행파일의 세그먼트


오브젝트 파일의 address부분을 보면 전부다 0이라는 사실을 알 수 있을것이다.

하지만 실행파일에는 올바른 주소가 적혀 있다.


여기서 링킹과정이 거칠때

오브젝트파일들을 합쳐서 주소를 정한다는 사실을 추가적으로 알수 있다.


블로그 이미지

powerprove

,


linux gcc에서 동적으로 컴파일 하는건 그냥 하면 되지만

정적으로 컴파일하는건 -static 옵션을 넣어야 한다.



그럼 정적으로 컴파일 했을때 얻는 장단점은 무엇일까?

원래 리눅스에서 동적으로 컴파일할때는 프로그램이 실행할때마다 libc(라이브러리)가 올라간다.

때문에 printf라는 함수를 실행시키기 위해서 libc에서 printf함수를 찾아서 실행시킨다.

하지만, 정적으로 컴파일하면 linking과정에서 함수가 다올라가게된다.

때문에 동적보다 속도는 빠르게 되지만, 함수가 프로그램에 올라가므로 파일 크기는 커지게 된다.



동적으로 컴파일 했을때는 파일크기가 8600이지만 정적으로 컴파일 햇을때는 파일크기가 9086000만큼 확연히 차이가 난다는 것을 알 수 있다.

블로그 이미지

powerprove

,

리눅스는 파일은 크게 3가지의 권한으로 이루어져 있다.

소유자 권한, 그룹 권한, 게스트 권한, 그리고 각각 읽기, 쓰기, 실행 권한이 있다.


이렇게 말하면 감이 안오니 직접 리눅스에서 눈으로 살펴보도록 하자.

확인하는 방법은 ls -al을 사용하면 된다.



간단하기 file1을보면

-rw-rw-r-- 1 powerprove powerprove 14 4월 ...   file1 이런식으로 되어 있을 것이다.

하나씩 살펴보면


-rw-rw-r--   : 이것이 파일 권한으로 뒤에서 자세히 다루자

                1   : 디렉토리의 링크 수를 나타낸다.

powerprove : 파일의 소유자를 나타낸다.

powerprove : 파일의 소유 그룹을 나타낸다.

                14 : 파일의 크기를 나타낸다.

4월 9 22:39  : 파일이 마지막으로 수정된 날짜를 나타낸다.

            file1  : 파일의 이름을 나타낸다.


우리는 

-rw-rw-r--을 자세히 보면된다.

이것은 크게 4가지로 쪼갤수 있다.

-     rw-       rw-     r--

첫번재는 파일이 디렉토리인지 아닌지 검사한다. 만약, 디렉토리라면 d가 적혀있다.

그리고 두번째가 소유자 권한

세번째가 그룹 권한

네번째가 게스트 권한이다.


r은 읽기권한

w은 쓰기권한

그리고 마지막인 x는 실행권한이다.


그러므로 file1은 소유자, 그룹에게 읽기권한과 쓰기권한이 있고 게스트사용자에겐 읽기권한만 있다는 것을 알 수 있다.

이것은 8진수로 나타낸다.

왜냐면 권한이 있다면 1, 없으면 0으로 나타내기 때문이다.


rwx    rw-

1 1 1    110

이런식으로 나타낼수 있다. 만약 읽기, 쓰기, 실행권한 전부다 있다면 숫자7로 나타낼수 있을 것이다.


우리는 이것을 이용하여  파일 권한을 바꿀수 있는데 chomd라는 명령어를 사용하면 된다.


사용법은

chmod [권한] [파일이름]으로 나타낸다.

권한은 각 권한들을 8진수로 나타낸 숫자를 적으면된다.

시험예시로 chmod 777을 입력해 보았다.



file1이 rwxrwxrwx로 바뀐것을 볼 수 있다. 

만약 소유자에게만 쓰기 권한을 주고 싶으면 chmod 755를 입력하면 될 것이다.


만약 파일의 소유자를 변경시키고 싶으면 어떻게 할까?

파일의 소유자를 변경시키는 명령어 또한 있다.

chown [소유자권한]:[그룹권한]  [파일이름] 이렇게하면 된다.


file1의 소유자가 root로 바뀐것을 볼 수있다.

만약 파일의 권한을 700(루트만 읽기, 쓰기, 실행)을 주면 어떻게 될까?



the -end


'system > level1' 카테고리의 다른 글

컴파일 과정(LINUX GCC)  (0) 2017.04.10
linux 정적 컴파일 동적 컴파일  (0) 2017.04.09
리눅스 기초(8086 메모리 구조)  (0) 2017.04.06
리눅스 기초(리눅스 디렉토리)  (0) 2017.04.04
리눅스 기초(리눅스 구조)  (0) 2017.04.04
블로그 이미지

powerprove

,

커널은 시스템이 부팅 될 때 커널을 메모리에 올린다.

32bit 시스템에서는 한번에 처리할수 있는 양이 32bit이다.


문제는 8086에서 세그멘테이션 기법과 페이징 기법중 무엇을 쓰냐가 헷갈렸는데

intel 8086에서는 둘다 사용한다.


세그멘테이션 기법과 페이징 기법의 가장 큰 차이는 

세그멘테이션 기법은 서로 크기가 다른 세그멘트를 분리한 후 물리 주소를 논리주소로 변환한다.

하지만 페이징 기법은 가상된 메모리를 고정된 크기로 나누어 메모리를 관리하는 것이다.


각각의 세그먼트들은 Code segment, Stack segment, Data segment로 나누어 진다. 


프로세스 메모리 구조를 자세히 보면



프로세스 메모리를 보면 kernel이 0xffffffff에서부터 0xc0000000로 메핑된다. 

code영역은 프로그램의 코드가 담겨져 있고 data영역은 rodata, bss, data로 나누어 진다.

rodata는 read only data로 읽기 권한만 가지고 있는 부분이다.

data부분은 전역변수 중 초기화 된 값을 가질 때 사용되고

bss부분은 전역변수 중 초기화 안된 값을 가질 때 사용된다.


지역변수는 stack에 들어간다. push and pop을 이용해서 데이터를 저장하고 빼낸다. stack은 위에서부터 밑으로 쓰고 heap(동적할당)부분은 밑에서부터 아래로 쓴다.

heap영역이 확장 될때는 brk라는 시스템 콜을 이용해서 확장 시킨다.

'system > level1' 카테고리의 다른 글

컴파일 과정(LINUX GCC)  (0) 2017.04.10
linux 정적 컴파일 동적 컴파일  (0) 2017.04.09
리눅스 파일 권한 설정  (0) 2017.04.09
리눅스 기초(리눅스 디렉토리)  (0) 2017.04.04
리눅스 기초(리눅스 구조)  (0) 2017.04.04
블로그 이미지

powerprove

,

리눅스 디렉토리 구조


루트(/)

절대경로 상태의 첫 꼭대기 디렉토리 이다.



/bin

리눅스의 기본적인 명령어 들이 저장된 디렉토리 이다.

root 사용자와 일반사용자가 함께 사용할 수 있다.


보면 rm, ls, ln 등이 있는 것을 확인 할 수 있다 . ㅎㅎ


/sbin


시스템 관리를 위한 명령들이 있음(루트 유저)


/home




사용자의 홈 디렉토리이다.


/root


루트의 홈 디렉토리이다.


/lib


라이브러리가 들어가 있다.

+ /usr/lib

/lib 에 없는 프로그램의 라이브러리가 들어가 있다.


/var


리눅스에서 자주 변경되는 데이터를 임시 저장하기 위한 장소


+ /var/log

로그가 저장됨



+ /var/run

시스템의 현재 정보가 들어있음


/boot


부팅에 필요한 파일이 저장됨(grub)



/usr


리눅스에서 가장 큰 공간을 사용하는 디렉토리로 일반사용자들이 사용한다.


+ /usr/bin

일반사용자들이 사용하는 명령어들


+ /usr/src/

커널 소스가 들어있는 디렉토리



'system > level1' 카테고리의 다른 글

컴파일 과정(LINUX GCC)  (0) 2017.04.10
linux 정적 컴파일 동적 컴파일  (0) 2017.04.09
리눅스 파일 권한 설정  (0) 2017.04.09
리눅스 기초(8086 메모리 구조)  (0) 2017.04.06
리눅스 기초(리눅스 구조)  (0) 2017.04.04
블로그 이미지

powerprove

,

리눅스는 유닉스 계열의 운영체제를 의미 한다.


리눅스의 특징


1.  대부분의 플랫폼에서 사용이 가능 하다.


2. 뛰어난 안정성과 보안성을 지닌다.

=> 커널 소스 코드 및 모든 관련 자료가 공개 되어 있기 때문!


3. 성능이 낮은 컴퓨터에서도 작동된다.


4. 멀티유저와 멀티테스킹이 가능하다.


5. 대부분의 리눅스는 무료이다.


6. 다양한 네트워크 서비스를 제공한다.

=> 다양한 프로토콜을 제공

=> 인터넷 기반 어플리케이션 제공

=> 다양한 웹서버를 제공한다.


리눅스 구조





리눅스의 구조는 (대략적으로) 이렇게 되어있다.  우리들은 쉘에 명령어를 입력함 으로서 우리가 원하는 명령어를 실행한다.

필요할경우 커널을 통해서 하드웨어 까지 제어할 수 있다.




쉘은 유저와 직접 소통하며 유저의 명령을 수행한다.

처음 ubuntu를 깔때는 bash쉘이 기본으로 되어있다.

zsh, ash, sh 등 많은 쉘이 있지만 필자는 oh my zsh을 쓴다!

윈도우의 cmd도 하나의 쉘이라고 볼 수 있다. 

/etc/shells 파일을 보면 사용할수 있는 쉘 목록이 있다.



/etc/passwd를 보면 사용자가 로그인시 사용하는 쉘이 있다. echo $SHELL로도 확인이 가능.



쉘을 바꾸고 싶으면 chsh를 이용하면 된다.


커널


커널은 운영체제에 가장 필요한 핵심이다.

커널은 처음 부팅될 때 메모리에 올라간다.

시스템의 여러 부분을 제어한다.

멀티태스크 환경을 제공한다. 멀티태스크는 여러개의 프로세스를 동시에 실행하는것을 의미한다.

시스템콜(syscall)을 이용해서 응용프로그램과 상호작용한다.

/proc/sys에 있는 특수 파일을 사용해 실시간으로 커널의 옵션을 설정하고 확인할 수 있다.

커널에 대한 자세한 공부는 6,7 월달에 자세히 공부해야 겠다...



'system > level1' 카테고리의 다른 글

컴파일 과정(LINUX GCC)  (0) 2017.04.10
linux 정적 컴파일 동적 컴파일  (0) 2017.04.09
리눅스 파일 권한 설정  (0) 2017.04.09
리눅스 기초(8086 메모리 구조)  (0) 2017.04.06
리눅스 기초(리눅스 디렉토리)  (0) 2017.04.04
블로그 이미지

powerprove

,