1.시스템 콜

OS에 리소스/서비스를 요청하려고 사용자 영역에서 시작해서 커널 내부로 들어가는 함수 호출

아키텍처 별로 시스템 콜의 수가 다르다


애플리케이션이 실행할 시스템 콜과 매개 변수를 레지스터를 통해 전달

시스템 콜은 0부터 시작하는 숫자로 나타내며 레지스터에 해당 시스템콜을 저장해야 함

시스템 콜 처리 과정은 컴파일러와 C 라이브러리에서 자동으로 처리



2.C 라이브러리


libc는 유닉스 애플리케이션의 핵심이며 다른 언어의 상위 레벨 라이브러리에 포함되어 코어 서비스와 시스템 콜을 처리하기 위해 동작한다

glibc: GNU C Library



3.C 컴파일러


GCC: 리눅스 표준 GNU C 컴파일러

C++ 시스템 프로그래밍에는 표준 C++ 라이브러리(libstdc++/libstdcxx)와 GNU C++ 컴파일러(g++)가 필요


API (Application Programming Interface)

 소스코드 레벨에서 서로 인터페이스 하는 방식 정의

 표준 인터페이스는 함수로 상위 레벨의 소프트웨어에서 하위 레벨의 소프트웨어를 호출

 API 구현체: 실제로 구현된 API


ABI (Application Binary Interface)

 특정 아키텍처 간 동작하는 소프트웨어 간의 바이너리 인터페이스 정의

 애플리케이션 내에서의 상호 동작, 커널과 애플리케이션, 애플리케이션과 라이브러리 간의 상호 동작에 대한 정의

 바이너리 호환성 보장하여 오브젝트 코드를 다시 컴파일하지 않고 같은 ABI 지원 시스템의 경우 동일한 기능을 수행하도록 보장

 콜링 컨벤션(함수 호출 방식, 인자 전달 방식, 레지스터 값 저장 방식, 반환값 가져가는 방식 등), 바이트 순서, 레지스터 활용, 시스템 콜 실행, 라이브러리 링크, 라이브러리 동작 방식, 바이너리 오브젝트 형식 등의 내용과 관련



4.파일과 파일시스템


 
리눅스는 모든 것이 파일이라고 여긴다. 따라서 모든 인터렉션은 실제 파일이 아닌 것 처럼 보일지라도 파일을 읽고 쓰는 것으로 이루어진다. 파일에 접근하여 읽기, 쓰기, 읽기/쓰기 모드로 열 수 있다. 열린 파일은 해당 파일에 대한 메타데이터와 연결된 고유한 기술자를 통해 참조할 수 있다. 커널 내부의 descriptor는 정수로 표현되며 file descriptor라고 부른다.(줄여서 fd) fd는 사용자 영역에서 공유되며 응용 프로그램이 파일에 접근할 때 직접 사용한다. 리눅스 시스템 프로그래밍 대부분은 fd를 열고 조작하고 닫는 작업이다.

 4.1.일반 파일
  
바이트 스트림이라 부르는 연속적으로 나열된 바이트 배열에 저장된 데이터를 의미. 리눅스 파일을 위한 특별한 자료구조는 없다.
 
파일은 바이트를 읽고 쓰는 것이 가능. 파일 내부의 위치를 지정해서 수행하는데 이 위치는 file offset 또는 file position이라고 한다. Offset은 커널이 열린 파일마다 유지하는 메타데이터의 핵심. 파일이 처음 열리면 offset0. 보통 파일은 바이트 단위로 읽고 쓰기 때문에 파일 오프셋 역시 바이트 단위로 증가하거나 감소한다. 직접 file offset을 지정 가능. 파일 끝을 넘어가는 위치를 지정하면 파일 끝 부터 지정 위치까지 0으로 채워진다. 하지만 파일 시작 위치보다 앞서 기록하는 것은 불가능. offset은 0부터 시작하며 음수가 될 수 없다. 파일 쓰기 작업은 대부분 파일 끝에서 일어나며 offset의 최대값은 offset 저장을 위해 사용되는 C 타입의 크기로 결정되며 최신 리눅스에서는 64비트 값이다.

파일 크기는 바이트 단위로 측정되며 파일 길이라 한다. truncation 연산을 통해 원래보다 작은 사이즈/큰 사이즈 상관없이 잘라낼 수 있으며, 빈 공간은 0으로 채워진다. 최대 파일 길이는 최대 file offset과 동일하며 C 타입 크기로 제한된다.

하나의 파일은 다른 프로세스나 동일 프로세스에서 한 번 이상 열 수 있다. 열릴 때 마다 고유 fd를 반환하며 프로세스에서 fd 공유 가능하다. 하나의 fd는 하나 이상의 프로세스에서 사용될 수 있다. 커널은 파일에 대한 동시 접근을 막지 않으며 여러 프로세스에서 동시에 같은 파일을 읽기/쓰기가 가능하다.

 파일은 inode 파일 시스템 내에서 고유한 정수 값으로 참조되며 inode는 디스크에 저장된 물리적 객체임과 동시에 커널에서 자료구조로 표현되는 논리적 개념이기도하다.


디렉터리와 링크

 inode 번호로 파일에 접근하려면 잠재적 보안 위협 등의 이유로 보통 사용자 영역에서 파일에 접근 시 inode 대신 파일 이름을 사용한다. 디렉터리는 파일에 접근하기 위한 이름을 제공하는데 inode 대신 사람이 읽을 수 있는 이름으로 나타낸다. 이 이름과 inode 쌍을 링크라 한다. 사용하는 파일 시스템에 맞게 이 링크를 관리하고 물리적으로 디스크에 저장하는 코드가 커널에 구현되어 있다. 디렉터리는 일반 파일과 비슷하지만 inode의 맵핑만 저장하고 커널이 이 맵핑을 이용해 이름으로 inode를 찾는다.

 inode에는 디스크에서 파일의 위치 같은 파일 관련 메타데이터가 있다.

 파일 경로 오픈 요청 시 커널은 해당 파일 경로에 속한 각 directory entry(dentry in kernel inside)를 탐색하여 다음 inode를 찾는다. 커널은 dentry 캐시를 사용하여 디렉터리 찾기 결과를 저장하고 나중에 일시적인 지역성을 활용해 탐색 속도를 높인다.

 커널은 사용자 영역에서 디렉터리를 일반 파일 처럼 열고 조작하지 못하도록 제한한다. 링크 추가/삭제 시스템 콜을 이용하여 조작한다. 커널 중재 없이 디렉터리 조작 시 단순 오류의 결과로 파일 시스템 전체가 망가질 수 있다.


하드링크

 다중 링크를 통하여 동일한 inode에 여러 이름을 맵핑할 수 있다. inode에서 파일 시스템 내부에 링크 카운터를 두어 자신을 가리키는 링크 개수를 추적하며 이 값이 0이 되면 파일시스템에서 inode와 관련 자료를 실제로 삭제한다.


심벌릭 링크

 링크로 연결할 파일의 완전한 경로 이름을 포함하는 독자적인 inode와 데이터가 담겨있다. 존재하지 않는 파일을 가리키는 심벌릭 링크를 꺠진 링크라 한다.

 하드링크보다 오버헤드를 많이 초래하는 이유는 심벌릭 링크를 효과적으로 탐색하기 위해 심벌릭 링크와 연결된 파일 둘 다 다뤄야 하기 때문이다. 오버헤드 크기는 작지만 부정적인 것으로 취급한다. 일종의 바로가기 처럼 동작한다.


특수 파일

 파일로 표현되는 커널 객체. block device, character device, named pipe, unix domain socket의 4종류 특수 파일 지원. 유닉스 시스템에서 하드웨어 장치 접근 또한 파일을 거쳐 실행 된다.

'System Engineering > Linux' 카테고리의 다른 글

FTP server set up  (0) 2018.06.16
Linux: swap  (0) 2018.06.11
리눅스 Core dump  (0) 2018.05.24
리눅스마스터 1급 2차 노트  (0) 2017.04.17
리마 1급 1차 노트  (0) 2017.01.31

+ Recent posts