# memblock: 사용할 RAM과 남겨 둘 RAM을 구분하기

v6.6 / mm/memblock.c

부팅 직후에는 일반 메모리 할당기가 아직 없습니다. 그렇지만 페이지 테이블과 커널 자료구조를 만들 RAM은 필요합니다. memblock은 RAM 구간과 예약 구간을 따로 기록하여, 이미 커널 이미지나 펌웨어가 쓰는 주소를 다시 나누어 주지 않도록 합니다. 여기서는 예약 정보를 등록하는 짧은 함수 전체를 읽습니다.

## memblock_reserve

```c

int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
{
	phys_addr_t end = base + size - 1;

	memblock_dbg("%s: [%pa-%pa] %pS\n", __func__,
		     &base, &end, (void *)_RET_IP_);

	return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);
}

```

### 871행

```c

int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)

```

base부터 size바이트를 예약 목록에 추가합니다. Linux v6.6의 이 함수는 주소와 크기 두 인자를 받으며 등록 결과를 반환합니다.

### 873행

```c

	phys_addr_t end = base + size - 1;

```

디버그 로그에 마지막으로 포함되는 바이트 주소를 출력하려고 끝 주소를 계산합니다. 내부 등록에는 base와 size를 그대로 사용합니다.

### 875행

```c

	memblock_dbg("%s: [%pa-%pa] %pS\n", __func__,

```

예약을 요청한 함수 이름과 물리 주소 구간을 memblock 디버그 출력에 남깁니다. %pa는 물리 주소를 담은 변수의 주소를 받습니다.

### 876행

```c

		     &base, &end, (void *)_RET_IP_);

```

시작·끝 주소와 호출 지점 _RET_IP_를 출력에 제공합니다. 이 버전은 여기서 nid와 flags를 인자로 받거나 출력하지 않습니다.

### 878행

```c

	return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);

```

reserved 목록에 범위를 추가합니다. NUMA 노드를 별도로 지정하지 않는 값 MAX_NUMNODES와 추가 속성 0을 넘기며 등록 결과를 반환합니다.

