[Linux, OS] Linux System Call | Memory Layout, Makefile | Git clone, commit, push, pull

pos++·2023년 11월 21일
0

Linux

목록 보기
10/16
post-thumbnail

2023.11.13 TIL
Code, Image source: The Linux Programming Interface, Michael Kerrisk

Linux OS가 제공하는 기능

  • Hardware Virtualization
  • Multiplex
  • Isolation
  • Sharing
  • Security
  • Performance

  • Process
  • Memory Allocation
  • File Contents
  • File Name, Directory
  • Access Control
  • User, IPC, Network, Time, Terminal

Linux System Call

Application은 system call을 통해 OS의 기능을 사용한다

fd = open("out", 1);
write(fd, "hello\n", 6);
pid = fork()

System Call이 호출되면 무슨 일이?

write()를 예시로

  1. User register와 PC를 Memory에 저장
  2. CPU를 kernel mode로 전환
  3. Memory 관리를 kernel page table로 변경
  4. Stack을 kernel stack으로 변경
  5. Kernel C code 점프

⭐ 가장 중요한 부분 → User code를 절대 kernel mode에서 실행시키면 안된다!!

copy

  • tlpi-dist/fileio/copy.c
  • Input file에서 Byte를 읽어서, output file에 쓰기
  • open()
    • File을 생성하고 file descriptor를 반환(또는 error(-1))
    • fd는 작은 ㅑinteger
    • Linux kernel은 process마다 fd index를 table로 관리
    • 내부적으로 일어나는 일
      • Function call처럼 보이지만, 실제로는 특별한 명령어
      • User register 저장 → Kernel mode로 전환 → Kernel entry point로 진입 → sys_open() → File system에서 이름 찾고 kernel data structure 수정 → User register 복구 → User mode로 전환
  • read(), write()
    • 첫번째 argument
      • File descriptor (fd)
        • 0 → standard input
        • 1 → standard output
        • 2 → standard error
    • 두번째 argument
      • Memory buffer
    • 세번째 argument
      • 읽을 Byte 수

fork

  • tlpi-dist/procexec/fork_whos_on_first.c
  • 새로운 process를 생성하는 system call
  • Shell: command로 새로운 process를 생성
    • Ex: $ echo hello
  • fork() system call은 새로운 process를 생성
    • 그대로 복사되는 것
      • Code, Data, Registers, File descriptors, current directory
    • 반환하는 PID
      • Parent: pid
      • Child: 0

exec

  • tlpi-dist/procexec/t_execl.c
  • Execution file로 호출한 process를 변경
    • Exec file(program) → 호출한 process
  • Program은 compiler에 의해 instruction과 Memory 초기값을 저장
  • exec([file name], [parameter]) → 호출한 현재 process를 교체
    • 호출한 process의 instruction과 memory값은 버림
    • File로부터 새로운 instruction과 memory 값을 읽음
    • 열린 file descriptor는 계속 유지

pipe

  • tlpi-dist/pipes/simple.pipe.c
  • IPC를 위한 기법
    • Ex: $ ls | grep -nr simple*
  • pipe() → 두개의 fd를 생성
    • 첫번째: read를 위한 fd
    • 두번째: write를 위한 fd

문제 발생…
구글링 아무리 해도 해결이 안된다.
gcc-multilib가 cross compiling을 도와주는건데 arm64에서 어떻게 설치하는지 모르겠다.
어떤 사람 말로는 기본적으로 gcc에 gcc-multilib가 포함돼있대서 걍 믿어보기로 한다.
일단 make 해서 빌드.


Memory Layout & Makefile

ELF(Executable and Linkable Format)

Linux 실행파일 format

.text → code

.rodata → read only data

.data → global C variable

Process Memory Layout

  • Text → Code, read-only data
  • Data → Global C variable
  • Stack → Function local variable
  • Heap → Dynamic memory allocation

ELF 분석 도구 (Binutils)

  • readelf -a ./copy
    • Execution file(elf) 분석 도구
    • glibc는 C library
    • text(code), initialized data, symbol table, debug info, …
  • objdump -S ./copy
    • 기계어로 번역
  • nm ./copy
    • Symbol 출력
  • file ./copy
    • File format 출력

Makefile

  • 대규모 program을 관리하는 tool
    • 기타 tools: maven, npm, yarn
  • gcc -o myprogram file1.c file2.c file3.c 이렇게 하지 않고‼️ makefile 을 사용함.

make : 소스 코드로 부터 실행 파일 또는 라이브러리를 생성하는 유틸리티

Makefile : make 명령어가 사용하는 스크립트 파일

  • 어떻게 컴파일 하는지
  • 어떤 파일을 컴파일 하는지

$ make -f [makefile name] target

strace

  • System call trace
  • $ strace ./copy seek_io seek_io_new → copy 실행시 생기는 system call들을 출력

tlpi Makefile 분석 과제

# Makefile to build all programs in all subdirectories
#
# DIRS is a list of all subdirectories containing makefiles
# (The library directory is first so that the library gets built first)
#

DIRS =	lib \
	acl altio \
	cap cgroups \
	daemons dirs_links \
	filebuff fileio filelock files filesys getopt \
	inotify \
	loginacct \
	memalloc \
	mmap \
	pgsjc pipes pmsg \
	proc proccred procexec procpri procres \
	progconc \
	psem pshm pty \
	shlibs \
	signals sockets \
	svipc svmsg svsem svshm \
	sysinfo \
	syslim \
	threads time timers tty \
	users_groups \
	vdso \
	vmem \
	xattr

# The "namespaces" and "seccomp" directories are deliberately excluded from
# the above list because much of the code in those directories requires a
# relatively recent kernel and userspace to build. Nevertheless, each of
# those directories contains a Makefile.

BUILD_DIRS = ${DIRS}

# Dummy targets for building and clobbering everything in all subdirectories

all:
	@ echo ${BUILD_DIRS}
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE}) ; \
		if test $$? -ne 0; then break; fi; done

allgen:
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE} allgen) ; done

clean:
	@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE} clean) ; done
  • DIRS → 하위 directory 목록
  • all → DIRS의 dir들 각각으로 cd $dir, make
    • $?-ne (not equal to) 0 → 마지막으로 실행된 command의 exit status가 0이 아닐 경우 (command failed), break
    • fiif문의 끝을 의미
  • allgen → DIRS의 dir들 각각으로 cd $dir, make allgen
  • clean → DIRS의 dir들 각각으로 cd $dir, make clean

GitHub - Ubuntu

# git 설치
$ sudo apt-get install git-core
$ git --version

$ git config --global user.name [내이름]
$ git config --global user.email [메일]
$ sudo git config --global color.ui "auto"

# git repository clone + connection setup
$ git clone https://github.com/glyserin/system-project.git
# 모든 file을 git stage에 추가
$ git add .

# file.txt만 git stage에 추가
$ git add file.txt

# stage 추가 된 파일 목록 보기
$ git status

# stage 추가 된 파일 commit
$ git commit -m "커밋내용"

# origin에 존재하는 branch로 push, 보통 초기에는 master branch를 사용한다.
$ git push origin main

# main에 올라간 변경사항 pull 해오기
# pull 하기 전에 내 변경사항 commit!!
$ git pull origin main
profile
밀린 TIL 업로드 조금씩 정리중...

0개의 댓글