728x90

10일 정도 안에 마칠 계획이고

보통은 WSL Ubuntu를 사용하겠지만 MAC을 가지고 있기 때문에 MAC을 이용해서 시스템 프로그래밍을 정리할 예정이다.

 

  • 시스템 프로그래밍의 개요

Systems programming, or system programming, is the activity of programming computer system software. The primary distinguishing characteristic of systems programming when compared to application programming is that application programming aims to produce software which provides services to the user directly (e.g. word processor), whereas systems programming aims to produce software and software platforms which provide services to other software, are performance constrained, or both - from wikipedia

 

시스템 프로그래밍은 시스템 호출을 이용해서 프로그램을 작성하는 것이다.

시스템 호출은 운영체제에서 제공하는 서비스를 프로그램에서 이용할 수 있도록 지원하는 프로그래밍 인터페이스를 의미한다.

 

시스템 프로그램은 시스템을 구성하는 자원을 다루는 프로그램이며 응용프로그램에 서비스를 제공하는 프로그램으로 OS, firmware, compiler 등이 있다.

 

프로그래밍을 하면서 라이브러리는 많이 사용을 해보았을 것이다.

Library function과 System call을 비교해보면

System call: 시스템의 기능을 이용하는 통로, Kernel 내 모듈을 직접 호출

Library function: 미리 컴파일 된 함수, 자주 사용되는 기능을 독립적으로 구현 (내부적으로 System call을 활용)

 

미리 만들어진 Library를 사용할 수 있지만 굳이 System programming을 배워 사용하는 이유는

직접 System call을 사용한다면 더 많은 것들을 만들 수 있으며 중간 과정을 건너 뛰고 직접 사용한다면 더 높은 성능을 얻을 수 있기 때문이다.

 

이 시스템 프로그래밍 공부의 목표는

  • 시스템을 효율적으로 활용하는 능력 함양

Unix/Linux 기반 시스템 및 새로 만나는 시스템

 

  • 시스템 자원에 대한 이해 향상

- File / Directory

- System information

- Process

- Signal

- Memory

- Communication interface

 

그냥 프로그램을 만드는 것이 아니라 더 높은 성능의 프로그램을 만들 수 있도록 시스템에 대해 이해하는 것이다.

 

  • Unix/Linux architecture

시스템 프로그래밍 중 사용할 Linux/Unix에 대해 알아보자

현재, 다양한 시스템에서 가장 널리 사용하는 OS이다.

 

Unix/Linux architecture

 

- Kernel

OS의 핵심 기능을 모아놓은것

 

-System call

OS 기능 중 응용프로그램이 사용하도록 허락된 기능들의 집합

 

-Shell

사용자와 OS 사이의 인터페이스

사용자의 입력을 해석하여 커널의 함수 호출

 

  • Basic Unix/Linux commands

- Login/Logout

telnet: 유닉스 시스템에 접속

이거는 잘 안써서 사용 방법을 모르겠다....

logout: 유닉스 시스템에서 접속해제

ex) logout

exit: 유닉스 시스템에서 접속해제

ex) exit

 

-Process management

ps: 현재 실생중인 프로세스를 출력

ex) ps -u 사용자ID

kill: process 강제 종료

ex) kill -9 사용자ID

 

-File/Directory

pwd: 현재 디렉토리 경로 출력

ex) pwd

ls: 디렉토리 내용 출력

ex) ls -l

cd: 현재 디렉토리 변경

ex) cd /tmp

cp: 파일/디렉토리 복사

ex) cp a.txt b.txt

mv: 파일/디렉토리 이름변경과 이동

ex) mv a.txt b.txt

rm: 파일/디렉토리 삭제

ex) rm a.txt

mkdir: 디렉토리 생성

ex) mkdir dir1

rmdir: 빈 디렉토리 삭제

ex) rmdir dir2

cat: 파일 내용 출력

ex) cat a.txt

more: 파일 내용을 쪽 단위로 출력

ex) more a.txt

chmod: 파일 접근권한 변경

ex) chmod 777 a.txt

grep: 패턴 검색

ex)grep abcd a.txt

 

- Others

su: 사용자 계정 변경

ex) su -seungkyu

tar: 파일/디렉토리 묶기

ex) tar cvf a.tar *

whereis: 파일 위치 검색

 

Man Page

Unix/Linux 시스템 사용 설명서로 

Shell command, System Call, Standard library에 대한 설명을 제공

 

man [options][section] page

의 명령어를 입력하여 사용한다.

 

  • VI editor

Linux를 사용하다보면 VI editor를 굉장히 많이 사용할 것이다.

일단 배운 명령어들로 실습을 할 디렉토리를 만들고 들어가준다.

그럼 이 실습 디렉토리에서 vi helloLinux.c 라는 명령어를 입력하여 VI 에디터를 실행해보자

VI 에디터로 helloLinux.c라는 C 소스코드 파일을 작성하겠다는 명령어이다.

 

그러면

이런 창이 나타나게 된다.

윈도우에서의 메모장이라고 생각하면 된다.

 

VI Editor의 명령어들이다.

입력모드 전환: i, a, o, O

한글자 수정: r

단어수정: cw

붙이기: p

글자삭제: x

명령취소: u, U

복사: y

행삭제: d

저장하고 종료: wq!

저장하지 않고 종료: :q!

 

명령어들은 외우려고 하기 보다 쓰다보면 자연스럽게 익혀지기 때문에 많이 사용해보는 것이 좋다.

정리하는 단계이니 일일이 소개하지는 않고

 

바로 프로그램을 만들어보도록 하겠다.

이렇게 작성을 하고 이 코드를 컴파일해보자

gcc -o helloLinux helloLinux.c

gcc를 이용해서 컴파일을 한다.

이렇게 입력을 하면 컴파일이 되고

./helloLinux를 이용해 컴파일이 된 프로그램을 실행할 수 있다.

 

 

  • Makefile

GNU C compiler는 Unix/Linux에서 가장 기본이 되는 compiler이다.

위에서 대충 사용해봤겠지만 자세한 사용 방법은 아래와 같다.

 

gcc [options] filename

options:

-c: object file(.o)만 생성

-o: execution file name 지정(default는 a.out이고 사용자가 이름 지정가능)

이렇게 -c 옵션을 주면 .o 파일을 만들 수도 있다.

Makefile & Make

컴파일을 도와주는 Make에 대해 알아보자

Makefile은 compile 방법을 기술 하는 파일이다.(관련 파일 정보, compile 명령, 실행 파일명 등), 여러 파일로 구성된 프로젝트 설정과 비슷한 개념

 

Make은 주어진 Makefile에 따라 compile을 수행하고, 실행파일을 생성. 최초 컴파일 이후에는, 변경이 있는 파일만 컴파일 함

 

Makefile을 사용하면

$ gcc -c -o main.o main.c
$ gcc -c -o foo.o foo.c
$ gcc -c -o bar.o bar.c

$ gcc -o app.out main.o foo.o bar.o

이렇게 항상 하나하나 모두 직접 컴파일을 해줘야 했던 일을

 

이렇게 미리 Makefile에 작성하여

app.out: main.o foo.o bar.o
	gcc -o app.out main.o foo.o bar.o
    
main.o: foo.h bar.h main.c
	gcc -c -o main.o main.c
    
foo.o: foo.h foo.c
	gcc -c -o foo.o foo.c
    
bar.o: bar.h bar.c
	gcc -c -o bar.o bar.c

$ make 명령어로 한 번에 컴파일 할 수 있다.

이렇게 미리 작성을 해두면 오타날 위험이 적다는 장점도 있다.

그리고 make를 할 때마다 모든 파일들을 컴파일 하는 것이 아니라 수정된 파일들만 찾아서 컴파일을 해주게 된다.

 

Rule block

Makefile의 Rule block은

<Target>: <Dependencies>
	<Recipe>

Target: Build 대상 이름, 일반적으로 최종 결과 파일명 사용

Dependency: Build 대상이 의존하는 Target이나 파일 목록

Recipe: Build 대상을 생성하는 명령어

 

Implicit rules

자주 사용되는 규칙을 자동으로 처리해줌(Source를 Compile해서 Object 파일을 생성하는 규칙)

Target에 대한 dependency까지는 명시를 해주어야 한다.

 

app.out: main.o foo.o bar.o
	gcc -o app.out main.o foo.o bar.o
    
main.o: foo.h bar.h main.c
foo.o: foo.h foo.c
bar.o: bar.h bar.c

이렇게 아래부분을 더 짧게 바꿀 수 있다.

 

variables

사용하는 명령어들과 파일 명들을 변수로 치환해서 사용할 수 있다.

CC=gcc
CFLAGS=-g pWall
OBJS=main.o foo.o bar.o
TARGET=app.out

$(TARGET): $(OBJS)
	$(CC) -o $@ $(OBJS) // $@: current target name
    
main.o: foo.h bar.h main.c
foo.o: foo.h foo.c
bar.o: bar.h bar.c

 

Clean rule

Build로 생성된 파일들 삭제하는 규칙

 

make로 파일을 만든 후에 필요 없어지는 파일들이 생길 수 있다.

그럴 때도 make 파일에 clean을 작성 한 후 한번에 제거할 수 있다.

clean:
    rm -f *.o
    rm -f $(TARGET)

이렇게 작성을 해둔 후

$make clean 명령어를 입력하면 clean에 작성된 명령어들이 한 번에 실행이 된다.

 

CC=gcc # (built-in variable) compiling C programs
CFLAGS=-g pWall # (built-in variable) extra flags to give to CC
OBJS=main.o foo.o bar.o
TARGET=app.out

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) -o $@ $(OBJS) // $@: current target name
    
main.o: foo.h bar.h main.c
foo.o: foo.h foo.c
bar.o: bar.h bar.c

clean:
    rm -f *.o
    rm -f $(TARGET)

이렇게 배워본 makefile을 정리해 보았다.

+ Recent posts