모든 브랜치를 보고 싶을 때

git branch -av

 

특정 브랜치/commit 으로 바꾸고 싶을 때

git checkout [branch 명/commit number]

 

내가 있는 경로의 git remote 저장소를 알고 싶을 때

git remote -v

 

gerrit push 명령어

git push refs/heads/[branch 명]


// <예시>
// master 브랜치에 push 하고 싶을 경우
// $ git push refs/heads/master

gerrit push 가 안될 경우?
→ commit message 에 Change-Id 가 없을 가능성이 큼.
→ 관련한 명령어는 추후 추가 예정. 보통은 error 메세지에 나온 명령어 그대로 입력하고 git commit --amend 로 commit 하면 Change-Id 가 추가 되어 다시 push 를 하면 push 가 됨.

 

Commit 한 뒤에 Commit 한 파일을 수정하고 싶을 때

// 수정하고 싶은 사항 수정 후, git status 로 수정한 파일 확인
git add [수정한 파일]
git commit --amend

 

 

N개 Commit 을 patch 파일로 만들고 싶을 경우

git format-patch -[N]

// <예시>
// 최신 commit 부터 3개 commit 을 patch 파일 생성하고 싶을 경우

// $ git format-patch -3

* patch 파일과 diff 파일의 차이
: git diff 로 생성판 파일은 파일을 수정한 내용만 있고 git format-patch 로 생성한 파일은 내부를 보면 소스 코드 수정 사항과 함께 commit 까지 포함되어 있다. commit message 까지 같이 전달하고 싶으면 git format-patch 로 patch 파일을 생성하여 전달하면 되고, 소스 코드 수정 사항만 내보내고 싶으면 git diff 로 diff 파일을 만들어 전달하면 된다.

 

staged 에 수정한 사항을 diff 로 저장하고 diff 파일을 적용할 때

// test.diff 에 수정 사항 저장
git diff > test.diff

// test.diff 를 적용
git apply test.diff

 

commit 한 사항을 patch 파일로 저장하고 patch 파일을 적용할 때

// commit 2개를 patch 파일로 만들기
git format-patch -2

// test.patch 파일을 git에 적용하기
git am test.patch

 

모든 수정 사항을 초기화하고 HEAD 로부터 commit N 개 아래 상태로 돌리고 싶을 때

git reset --hard HEAD~[N]

 // <예시>
 // 최신 commit 에서부터 2개 이전 commit 으로 돌아가고 싶을 때
 // git reset --hard HEAD~2

* 신규로 생성한 파일은 지워지지 않는다.

 

CPU 32 bit 의 경우 사용 가능한 가상 주소 범위는 이론 상 4 GB

=> 2^32 = 4 * 1024 * 1024 * 1024 = 4GB
기본적으로 User 가 3 GB, Kernel 이 1 GB 할당을 받는다. 옵션에 따라 변경은 가능하다. (64 bit 의 경우, 128 테라, 128 테라)

커널은 1G 를 어떻게 사용하는가?
- 선매핑용 주소 (896G) : 커널 내부에서 사용하는 지역 변수나 동적 할당 변수가 저장됨. DMA 주소 포함
- 후매핑용 주소 (128M) : 나중에 물리 메모리를 연결해서 사용할 용도로 남겨둠. vmalloc, pkmap area 주소, fixmap area 주소

 

CPU 64 bit 의 경우 사용 가능한 가상 주소 범위는 이론 상 16 * 1024 * 1024 TB

=> 2^64 = 16 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 = 16 * 1024 * 1024 TB

 

 

4 Level Page Table

가상 주소 9 bit (PGD-Global) + 9 bit (PUD-Upper) + 9 bit (PMD-Middle) + 12 bit (Page Table) = 가상 주소 48 bit 사용

  • PGD: Page Global Directory
  • PUD: Page Upper Directory
  • PMD: Page Middle Directory

 

 

 

 

Page Table Entry 가 커버하는 메모리 사이즈

arch/x86/include/asm/page_table.h 파일에서 다음을 확인할 수 있다.

/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT              12

위의 의미는 Page Table Entry 하나가 커버하는 크기는 2^12 = 4 * 1024 = 4KB 인 것을 확인할 수 있다.

 

arch/x86/include/asm/pgtable_64_types.h 에서 다음을 확인 할 수 있다.

/*
 * PMD_SHIFT determines the size of the area a middle-level
 * page table can map
 */
#define PMD_SHIFT       21
#define PTRS_PER_PMD    512

PMD 가 하나 할당 될 경우 PMD_SHIFT 는 9 + 12 bit = 21 bit
따라서 Page Middle Directory 의 하나의 entry 가 커버하는 크기는 2^21 = 2 * 1024 * 1024 = 2 MB 커버 가능

 

부팅 직후 Board 에서 확인할 수 있는 방법

/sys/kernel/debug/page_tables/current_kernel 내용에서 pmd 개수를 알아 낼 수 있다.

 

'Linux' 카테고리의 다른 글

MMAP  (0) 2022.12.18
Page Fault 관련 정리  (0) 2022.12.15
리눅스 프로그램과 커널 프로그램  (0) 2022.12.09
리눅스 운영체제의 구성  (0) 2022.12.09
커널 분석 및 디버깅 툴; uftrace  (0) 2022.12.09

mmap 이란 가상 주소 공간(VMA; Virtual Memory Address) 할당 하는 것을 말한다. 파일과 가상 주소를 맵핑할 수도 있다. malloc() 함수도 기본적으로 heap(VMA) 에서 가상 주소 공간을 할당하지만 더 큰 할당이 필요할 때는 내부적으로 mmap 을 통해서 가상 주소 공간을 할당한다.

 

task_struct : Task (혹은 Process) 관리 목적의 커널 자료 구조
ㄴ mm_struct : task_struct 구조체의 하위 자료 구조. 가상 메모리 관리 목적의 커널 자료 구조.
    ㄴ vma: 가상 메모리 공간을 관리하는 자료구조 (예시: stack, heap, code .. 등등)

* Anonymous Page 란? 파일과 매핑이 안된 VMA / Page (예: stack, heap ..)

 

mmap 사용 예시

file 을 열어서 읽고 쓰는 것과 비슷하게 다음 과정을 거치면 메모리를 할당 받아 사용할 수 있다.

  • open()
  • mmap() : malloc 과 거의 동일. 요구한 만큼의 용량 만큼 메모리를 할당하고 할당된 메모리 포인터를 반환.
  • memset()
  • munmap() : 메모리 할당 해제
  • close()

* pagecache 란? 파일과 매핑이 된 Page

 

* 메모리 상에 유지하고 있는 disk cache 버리는 방법

echo 3 > /proc/sys/vm/drop_caches

proc 의 man 페이지를 통해서 proc 사용 방법을 확인할 수 있다.

 

mmap 과 read 시스템콜 비교

  • read 시스템콜의 경우, read를 할 때마다 시스템콜이 발생하여 user mode -> kernel mode 로 넘어가야 하는 overhead 발생
  • mmap 의 경우, 가상 메모리와 물리 메모리가 바로 연결되어 있음. 배열로 된 페이지 테이블을 참고하여 바로 물리 메모리에 접근할 수 있어 속도가 빠름

 

 

'Linux' 카테고리의 다른 글

4-Level Page Table  (0) 2022.12.18
Page Fault 관련 정리  (0) 2022.12.15
리눅스 프로그램과 커널 프로그램  (0) 2022.12.09
리눅스 운영체제의 구성  (0) 2022.12.09
커널 분석 및 디버깅 툴; uftrace  (0) 2022.12.09

강의 들으면서 핵심 내용만 간단하게 정리 진행 중....

 

 

 

 

Memory 관련 Linux Register

CR0: Real mode vs Protection mode 구분 가능 (?)

CR2: 페이지폴트를 일으킨 가상 주소 저장 

CR3:현재 프로세스의 페이지테이블의 주소 (Vritual Adress - Phsical Address 매핑 테이블)

참고할만 한 자료: https://blackcon.tistory.com/117

 

Page Fault

x86 의 경우 Page Fault error code 는 다음과 같다.

arch/x86/include/asm/traps.h

/*
 * Page fault error code bits:
 *
 *   bit 0 ==    0: no page found   1: protection fault
 *   bit 1 ==    0: read access     1: write access
 *   bit 2 ==    0: kernel-mode access  1: user-mode access
 *   bit 3 ==               1: use of reserved bit detected
 *   bit 4 ==               1: fault was an instruction fetch
 *   bit 5 ==               1: protection keys block access
 */

arm 의 경우는 다르며 arch/arm64/include/asm/traps.h 에는 없음. 정리된 주석이 없어 더 살펴봐야 함

 

 

Page Fault 발생 시점의 Stack Trace

page fault가 발생한 지점의 stack trace

exec 하면서 Page fault 가 날 수도 있고, 여러 경우가 있음

 

Page Fault Handler 주요 흐름

Page Fault Handling 이라 함은 페이지 변환 테이블을 수정하는 것이다. 다음과 같은 일을 한다.

(1) 물리 메모리 (Page Frame) 할당
(2) Virtual Address 와 Physical Adrdress 연결
(3) Page Table 한 요소 (entry) flag 세팅
 *PTE: Page Table Entry

Interrupt 나 Exception 이 호출될 때 Entry 에서 시작한다. Page Fault 라는 Exception이 시작하는 부분은 x86 의 경우 arch/x86/entry/entry_64.S 에서 시작한다.

arch/x86/entry/entry_64.S 의 한 부분이 다음과 같다.

idtentry page_fault             do_page_fault           has_error_code=1        read_cr2=1

page_fault 가 호출되면 c로 된 do_page_fault 함수를 호출하고 has_error_code와 read_cr2 (cr2는 fault 가 났을 때 가상 메모리 주소)를 인자로 받아간다.

mm/fault.c 에서 do_page_fault 함수를 확인할 수 있다.

dotraplinkage void
do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
{
        enum ctx_state prev_state;

        prev_state = exception_enter();
        trace_page_fault_entries(regs, error_code, address);
        __do_page_fault(regs, error_code, address);
        exception_exit(prev_state);
}
NOKPROBE_SYMBOL(do_page_fault);

arm 의 경우에는 entry 가 아닌 다른 진입점이 있을 것으로 예상함. do_page_fault 는 있으나 .S 파일이 없음

 

__do_page_fault 는 arch/x86/mm/fault.c에서 다음과 같다.

static noinline void
__do_page_fault(struct pt_regs *regs, unsigned long error_code,
		unsigned long address)
{


...

unlikely 란 if 의 결과 값을 예상하고 미리 분기를 하는 함수. 강의 내용이 커널 3점대 버전으로 진행되는 것 같다. 5점 대 버전에서는 x86 에 상단 내용이 없음.

 

주된 내용만 살펴보면 page fault 핸들링은 다음과 같이 동작한다.

do_user_addr_fault()   : arch/x86/mm/fault.c
  -> handle_mm_fault()    :   mm/memory.c
      -> __handle_mm_fault()    :   mm/memory.c
          -> handle_pte_fault()     :   mm/memory.c
               -> ptep_set_access_flags()   :  arch/x86/mm/pgtable.c
                    -> set_pte() “페이지 테이블 한요소(pte) 수정”

 

 

task_struct 구조체: task (process) 관리 목적의 커널 자료 구조

ㄴ mm_struct : task_struct 하위 구조체. 가상 메모리 관리 목적의 커널 자료 구조.

    ㄴ vma : mm_struct 의 하위. 가상 메모리 공간을 관리하는 자료 구조. stack 공간, heap 공간, code 공간.

 

 

'Linux' 카테고리의 다른 글

4-Level Page Table  (0) 2022.12.18
MMAP  (0) 2022.12.18
리눅스 프로그램과 커널 프로그램  (0) 2022.12.09
리눅스 운영체제의 구성  (0) 2022.12.09
커널 분석 및 디버깅 툴; uftrace  (0) 2022.12.09

리눅스 프로그램

  • c 언어 파일을 컴파일 하면 ELF 파일이 생성
  • ELF 란 Excutable and Linkage Format
  • 바이너리 분석 프로그램
    • readelf
    • objdump

 

 

 

'Linux' 카테고리의 다른 글

4-Level Page Table  (0) 2022.12.18
MMAP  (0) 2022.12.18
Page Fault 관련 정리  (0) 2022.12.15
리눅스 운영체제의 구성  (0) 2022.12.09
커널 분석 및 디버깅 툴; uftrace  (0) 2022.12.09

+ Recent posts