Ryotta's Linux 7.0 MM

메모리 관리 서브시스템 완전 분석

ARM64 vs x86_64 메모리 관리 차이점

Linux 7.0 기준 · 마지막 갱신: 2026-06-26

개요 (Overview)

ARM64와 x86_64는 Linux 커널에서 메모리 관리를 구현하는 아키텍처입니다. 두 아키텍처는 공통적으로 4단계 또는 5단계 페이지 테이블을 사용하지만, 하드웨어 설계 철학이 다르기에 세부 구현에서 상당한 차이가 발생합니다. x86_64는 강력한 일관성(Coherent) 메모리 모델을 기반으로 하여 소프트웨어가 명시적 배리어를 적게 사용하는 반면, ARM64는 강건한(Relaxed) 일관성 모델을 사용하므로 드라이버와 커널 코드에서 명시적 메모리 배리어를 더 많이 사용해야 합니다.

이 문서에서는 Linux 7.0 소스 코드를 기반으로 두 아키텍처의 메모리 관리 차이점을 분석합니다. 페이지 테이블 구조, TLB 관리, 메모리 배리어, Huge Page 지원, DMA 코히어런스, NUMA 구현 등 핵심 영역을 다룹니다. 각 아키텍처별 특성을 이해하면 커널 코드 최적화와 드라이버 개발에 큰 도움이 됩니다.

일상 비유로 보면 각 프로세스는 자기만의 도서관 지도(VA)를 들고 있고, MMU가 그 지도를 실제 서가(PA)로 바꿉니다. ARM64는 안내판을 더 자주 다시 붙여야 하는 쪽이고, x86_64는 기본 질서를 더 강하게 유지하는 쪽이라고 보면 이해가 쉽습니다.

소스 파일 경로:

arch/arm64/include/asm/pgtable.h          ← ARM64 페이지 테이블
arch/arm64/include/asm/pgtable-hwdef.h    ← ARM64 페이지 테이블 하드웨어 정의
arch/arm64/include/asm/tlbflush.h         ← ARM64 TLB 플러시
arch/arm64/include/asm/barrier.h          ← ARM64 메모리 배리어
arch/arm64/include/asm/memory.h           ← ARM64 메모리 맵
arch/arm64/include/asm/hugetlb.h          ← ARM64 HugeTLB
arch/x86/include/asm/pgtable.h            ← x86_64 페이지 테이블
arch/x86/include/asm/pgtable_types.h      ← x86_64 페이지 테이블 타입
arch/x86/include/asm/pgtable_64.h         ← x86_64 페이지 테이블 (64비트)
arch/x86/include/asm/tlb.h                ← x86_64 TLB 관리
arch/x86/include/asm/tlbflush.h           ← x86_64 TLB 플러시
arch/x86/include/asm/barrier.h            ← x86_64 메모리 배리어

빠른 점검 명령

# 현재 시스템 아키텍처 확인
uname -m

# 페이지 테이블 레벨 확인 (CONFIG_PGTABLE_LEVELS)
cat /boot/config-$(uname -r) | grep PGTABLE_LEVELS

# Huge Page 지원 확인
cat /proc/meminfo | grep -i huge

# NUMA 노드 정보 확인
numactl --hardware

# 메모리 배리어 관련 커널 심볼 확인
cat /proc/kallsyms | grep -E "dsb|dmb|isb|mfence|lfence|sfence"

# 페이지 크기 확인
getconf PAGESIZE

# 커널 설정에서 아키텍처 관련 옵션 확인
cat /boot/config-$(uname -r) | grep -E "ARM64|X86"

# TLB 관련 정보 확인
dmesg | grep -i tlb

# 메모리 맵 확인
cat /proc/iomem | head -20

# DMA 관련 정보 확인
cat /proc/dma

# 페이지 폴트와 메모리 압력 확인
cat /proc/vmstat | grep -E "pgfault|pgmajfault"
cat /proc/pressure/memory

# 아키텍처별 페이지 테이블 덤프 확인 (debugfs 활성화 시)
sudo cat /sys/kernel/debug/kernel_page_tables | head -40

핵심 자료구조

1. ARM64 페이지 테이블 엔트리 (PTE)

ARM64 PTE는 64비트 엔트리로 다양한 플래그를 포함합니다.

// arch/arm64/include/asm/pgtable-hwdef.h:164-176
#define PTE_VALID       (_AT(pteval_t, 1) << 0)    // 유효 비트
#define PTE_USER        (_AT(pteval_t, 1) << 6)    // AP[1] - 사용자 접근 가능
#define PTE_RDONLY      (_AT(pteval_t, 1) << 7)    // AP[2] - 읽기 전용
#define PTE_SHARED      (_AT(pteval_t, 3) << 8)    // SH[1:0] - 내부 공유 가능
#define PTE_AF          (_AT(pteval_t, 1) << 10)   // 접근 플래그
#define PTE_NG          (_AT(pteval_t, 1) << 11)   // 비전역 플래그
#define PTE_DBM         (_AT(pteval_t, 1) << 51)   // 더티 비트 관리
#define PTE_CONT        (_AT(pteval_t, 1) << 52)   // 연속 범위
#define PTE_PXN         (_AT(pteval_t, 1) << 53)   // 특권 실행 불가
#define PTE_UXN         (_AT(pteval_t, 1) << 54)   // 사용자 실행 불가

특징:

  • PTE_DBM: 하드웨어 더티 비트 관리 (ARM64 고유)
  • PTE_CONT: 연속 페이지 매핑 (성능 최적화)
  • PTE_UXN: NX 비트와 유사하지만 실행 불가 영역 분리 가능
  • 2. x86_64 페이지 테이블 엔트리 (PTE)

    x86_64 PTE는 64비트 엔트리로 NX 비트와 다양한 소프트웨어 비트를 포함합니다.

    // arch/x86/include/asm/pgtable_types.h:51-58
    #define _PAGE_PRESENT   (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)  // 존재 비트
    #define _PAGE_RW        (_AT(pteval_t, 1) << _PAGE_BIT_RW)       // 읽기/쓰기
    #define _PAGE_USER      (_AT(pteval_t, 1) << _PAGE_BIT_USER)     // 사용자 접근
    #define _PAGE_PWT       (_AT(pteval_t, 1) << _PAGE_BIT_PWT)      // 페이지 쓰기 통과
    #define _PAGE_PCD       (_AT(pteval_t, 1) << _PAGE_BIT_PCD)      // 페이지 캐시 비활성화
    #define _PAGE_ACCESSED  (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED) // 접근됨
    #define _PAGE_DIRTY     (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)    // 더티
    #define _PAGE_PSE       (_AT(pteval_t, 1) << _PAGE_BIT_PSE)      // Huge Page

    특징:

  • _PAGE_NX: 실행 불가 비트 (bit 63)
  • _PAGE_PSE: Huge Page 지원
  • _PAGE_PAT: 페이지 속성 테이블
  • _PAGE_SOFT_DIRTY: 소프트웨어 더티 트래킹
  • 3. ARM64 메모리 타입 (MAIR)

    ARM64는 MAIR (Memory Attribute Indirection Register)를 사용하여 메모리 속성을 정의합니다.

    // arch/arm64/include/asm/memory.h:171-176
    #define MT_NORMAL           0  // 일반 메모리 (WB, 캐시 가능)
    #define MT_NORMAL_TAGGED    1  // 태그된 일반 메모리 (MTE용)
    #define MT_NORMAL_NC        2  // 비캐시 메모리
    #define MT_DEVICE_nGnRnE    3  // 디바이스 메모리 (강건한 Ordering)
    #define MT_DEVICE_nGnRE     4  // 디바이스 메모리 (약한 Ordering)

    4. x86_64 캐시 모드

    x86_64는 PAT (Page Attribute Table)와 MTRR를 사용하여 캐시 모드를 관리합니다.

    // arch/x86/include/asm/pgtable_types.h:167-176
    enum page_cache_mode {
        _PAGE_CACHE_MODE_WB       = 0,  // Write-Back
        _PAGE_CACHE_MODE_WC       = 1,  // Write-Combining
        _PAGE_CACHE_MODE_UC_MINUS = 2,  // Uncached minus
        _PAGE_CACHE_MODE_UC       = 3,  // Uncached
        _PAGE_CACHE_MODE_WT       = 4,  // Write-Through
        _PAGE_CACHE_MODE_WP       = 5,  // Write-Protect
        _PAGE_CACHE_MODE_NUM      = 8
    };

    핵심 함수

    1. ARM64 TLB 플러시 (`__tlbi`)

    // arch/arm64/include/asm/tlbflush.h:32-42
    #define __TLBI_0(op, arg) asm (ARM64_ASM_PREAMBLE \
                       "tlbi " #op "\n" \
                    : : )
    
    #define __TLBI_1(op, arg) asm (ARM64_ASM_PREAMBLE \
                       "tlbi " #op ", %x0\n" \
                    : : "rZ" (arg))
    
    #define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
    
    #define __tlbi(op, ...)     __TLBI_N(op, ##__VA_ARGS__, 1, 0)

    특징: ARM64는 TLBI 명령어를 사용하여 브로드캐스트 방식으로 TLB를 무효화합니다.

    2. x86_64 TLB 플러시 (`invlpg`)

    // arch/x86/include/asm/tlb.h:26-29
    static inline void invlpg(unsigned long addr)
    {
        asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
    }

    특징: x86_64의 기본 경로는 invlpg로 개별 페이지를 무효화하며, 일부 확장 경로에서는 INVLPGB 같은 범위 무효화도 다룹니다.

    3. ARM64 메모리 배리어

    // arch/arm64/include/asm/barrier.h:27-29, 63-65
    #define isb()       asm volatile("isb" : : : "memory")
    #define dmb(opt)    asm volatile("dmb " #opt : : : "memory")
    #define dsb(opt)    asm volatile("dsb " #opt : : : "memory")
    
    #define __mb()      dsb(sy)
    #define __rmb()     dsb(ld)
    #define __wmb()     dsb(st)

    특징: ARM64는 명시적 배리어 명령어를 사용하여 메모리 일관성을 보장합니다.

    4. x86_64 메모리 배리어

    // arch/x86/include/asm/barrier.h:22-24
    #define __mb()  asm volatile("mfence":::"memory")
    #define __rmb() asm volatile("lfence":::"memory")
    #define __wmb() asm volatile("sfence" ::: "memory")

    특징: x86_64는 강건한 메모리 모델을 사용하므로 많은 경우 배리어가 불필요합니다.

    5. ARM64 HugeTLB 설정

    // arch/arm64/include/asm/hugetlb.h:35-36
    pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
    #define arch_make_huge_pte arch_make_huge_pte

    특징: ARM64는 PTE_CONT 비트를 사용하여 연속 페이지 매핑을 최적화합니다.


    호출 흐름

    ARM64 페이지 폴트 처리

    do_page_fault()
      → do_mem_abort()
        → do_translation_fault()
          → handle_mm_fault()
            → __handle_mm_fault()
              → handle_pte_fault()
                → do_anonymous_page()    // 익명 페이지
                → do_fault()             // 파일 기반 페이지
                → do_wp_page()           // COW (Copy-on-Write)
                → do_numa_page()         // NUMA 페이지

    x86_64 페이지 폴트 처리

    exc_page_fault()
      → do_user_addr_fault()
        → handle_mm_fault()
          → __handle_mm_fault()
            → handle_pte_fault()
              → do_anonymous_page()    // 익명 페이지
              → do_fault()             // 파일 기반 페이지
              → do_wp_page()           // COW (Copy-on-Write)
              → do_numa_page()         // NUMA 페이지

    차이점: ARM64는 do_mem_abort()를 통해 하드웨어 폴트를 처리하고, x86_64는 exc_page_fault()를 통해 인터럽트 기반으로 처리합니다.

    두 경로 모두 결국 handle_mm_fault()로 모이고, 이후에는 do_anonymous_page(), do_fault(), do_wp_page(), do_numa_page() 같은 공통 처리로 갈라집니다. minor fault는 PTE만 채우는 경우가 많고, major fault는 파일 I/O를 동반하며, 권한 위반이나 잘못된 주소는 SIGSEGV로 끝납니다.


    조건별 비교

    1. 페이지 테이블 구조 비교

    항목ARM64x86_64
    **페이지 테이블 레벨**4단계 (VA_BITS=48) 또는 5단계 (VA_BITS=52)4단계 (4-level) 또는 5단계 (5-level, LA57)
    **페이지 크기**4KB, 16KB, 64KB 선택 가능4KB 고정 (2MB Huge, 1GB Huge)
    **PTE 비트 수**64비트 (50비트 물리 주소)64비트 (52비트 물리 주소)
    **NX 비트**PTE_UXN, PTE_PXN (2비트)_PAGE_NX (1비트)
    **더티 비트**하드웨어 지원 (PTE_DBM)하드웨어 지원 (_PAGE_DIRTY)
    **접근 플래그**PTE_AF_PAGE_ACCESSED

    2. TLB 관리 비교

    항목ARM64x86_64
    **TLB 플러시 명령어**TLBI (브로드캐스트)invlpg (기본, 개별 페이지)
    **무효화 범위**ASID 기반, 페이지/테이블/전체PCID/ASID 기반, 페이지/전체
    **동기화**DSB + ISB 필요TLBSYNC 필요
    **레이지 모드**TIF_LAZY_MMU_PENDING 지원없음
    **성능**브로드캐스트 오버헤드 발생 가능로컬 처리 우선

    3. 메모리 배리어 비교

    항목ARM64x86_64
    **메모리 모델**강건한 (Relaxed)강력한 (Strong)
    **전체 배리어**DSB SYMFENCE
    **읽기 배리어**DSB LDLFENCE
    **쓰기 배리어**DSB STSFENCE
    **DMA 배리어**DMB OSHbarrier() (불필요)
    **명령어 동기화**ISB없음

    4. Huge Page 지원 비교

    항목ARM64x86_64
    **THP 크기**2MB (PMD), 연속 PTE (CONT_PTE)2MB (PMD), 1GB (PUD)
    **연속 매핑**PTE_CONT (16페이지), PMD_CONT (128페이지)없음
    **Contiguous 비트**하드웨어 지원 (PTE_CONT)없음
    ** HugeTLB**기본 지원기본 지원

    5. DMA 코히어런스 비교

    항목ARM64x86_64
    **DMA 일관성**IOMMU 또는 하드웨어 코히어런스하드웨어 코히어런스
    **배리어**DMB OSH (DMA 배리어)barrier() (불필요)
    **IOMMU**SMMU (System MMU)VT-d, AMD-Vi
    **DMA 영역**DMA 영역 할당 지원DMA 영역 할당 지원

    6. NUMA 구현 비교

    항목ARM64x86_64
    **NUMA 구현**ACPI SRAT 또는 DTACPI SRAT
    **거리 계산**추상 거리 모델ACPI SLIT
    **자동 NUMA**AutoNUMA 지원AutoNUMA 지원
    **메모리 정책**기본 정책 + NUMA 정책기본 정책 + NUMA 정책

    빠른 점검 명령 상세

    # 1. 아키텍처별 페이지 테이블 레벨 확인
    # ARM64
    cat /proc/cpuinfo | grep -i "page table"
    # x86_64
    cat /proc/cpuinfo | grep -i "pge\|pse\|pdpe1gb"
    
    # 2. Huge Page 설정 확인
    cat /proc/meminfo | grep -i huge
    cat /sys/kernel/mm/transparent_hugepage/enabled
    
    # 3. NUMA 메모리 정책 확인
    numactl --show
    cat /proc/sys/vm/numa_balancing
    
    # 4. 메모리 배리어 관련 모듈 확인
    lsmod | grep -E "kvm|vfio|iommu"
    
    # 5. 커널 메모리 맵 확인
    cat /proc/kallsyms | grep -E "vmalloc_start|vmalloc_end"
    
    # 6. DMA 관련 정보 확인
    cat /proc/dma
    cat /sys/class/dma/*/in_use
    
    # 7. 페이지 할당기 통계 확인
    cat /proc/buddyinfo
    cat /proc/pagetypeinfo
    
    # 8. SLAB 통계 확인
    cat /proc/slabinfo
    slabtop
    
    # 9. 메모리 압력 확인
    cat /proc/pressure/memory
    
    # 10. 커널 설정에서 아키텍처 관련 옵션 확인
    # ARM64
    zcat /proc/config.gz | grep ARM64
    # x86_64
    zcat /proc/config.gz | grep X86

    관련 문서

  • 00-overview.html - 메모리 관리 개요
  • 01-page_alloc.html - Buddy Allocator
  • 02-slab.html - SLUB 할당자
  • 03-vma_mmap.html - VMA / mmap
  • 38-pagewalk.html - Page Table Walk
  • 10-hugepage.html - Huge Pages / THP
  • 13-numa.html - NUMA
  • 20-migrate.html - Migration

  • 참고 자료

  • ARM Architecture Reference Manual
  • Intel 64 and IA-32 Architectures Software Developer's Manual
  • Linux Kernel Documentation - Memory Management
  • ARM64 Memory Management