# 이미지에 패키지 추가 및 제거

이미지에 원하는 패키지를 추가하거나 불필요한 패키지를 제거하는 것은 Yocto 프로젝트의 중요한 기능 중 하나이다. 이를 통해 최적화된 임베디드 리눅스 시스템을 생성할 수 있다.

#### 패키지 추가

**`IMAGE_INSTALL` 변수 사용**

Yocto에서는 `IMAGE_INSTALL` 변수를 사용하여 이미지를 생성할 때 추가로 설치할 패키지를 지정할 수 있다. `IMAGE_INSTALL` 변수는 local.conf 파일이나 특정 레시피에서 정의할 수 있다.

```sh
IMAGE_INSTALL_append = " 패키지명1 패키지명2"
```

* `_append` 접미사를 사용하여 기존의 `IMAGE_INSTALL` 내용에 패키지를 추가할 수 있다.

예를 들어, `local.conf`에 다음과 같이 작성할 수 있다:

```sh
IMAGE_INSTALL_append = " nano wget"
```

이렇게 하면 기본 이미지에 nano와 wget 패키지가 추가된다.

**레시피에서 패키지 추가**

특정 레시피에서 `IMAGE_INSTALL` 변수를 설정하여 패키지를 추가할 수도 있다. 예를 들어, 커스텀 이미지 레시피 `my-image.bb`를 작성하여 그 안에 `IMAGE_INSTALL`을 설정할 수 있다:

```sh
IMAGE_INSTALL += " nano wget"
```

**유효성 검사**

추가된 패키지가 제대로 설치되었는지 확인하려면 빌드 후에 이미지 파일 시스템을 검사하거나 실제 하드웨어/에뮬레이터에서 부팅하여 확인할 수 있다. `bitbake -c populate_sdk` 명령어를 통해 SDK를 생성하여 개발 환경에서도 확인 가능한다.

#### 패키지 제거

**`IMAGE_INSTALL_remove` 변수 사용**

패키지를 제거하려면 `IMAGE_INSTALL_remove` 변수를 사용할 수 있다. 이 변수는 특정 패키지를 이미지에서 제거하는 데 사용된다.

```sh
IMAGE_INSTALL_remove = " 패키지명"
```

예를 들어, `local.conf`에 다음과 같이 작성할 수 있다:

```sh
IMAGE_INSTALL_remove = " nano"
```

이렇게 하면 기본 이미지에서 nano 패키지가 제거된다.

**레시피에서 패키지 제거**

특정 레시피에서 패키지를 제거하려면 `IMAGE_INSTALL_remove` 변수를 같이 사용하면 된다. 예를 들어, 커스텀 이미지 레시피 `my-image.bb`를 작성하여 그 안에 `IMAGE_INSTALL_remove`을 설정할 수 있다:

```sh
IMAGE_INSTALL_remove += " nano"
```

**불필요한 패키지 식별**

특정 패키지가 제거 가능한지 확인하려면 이미지의 패키지 목록을 조사해야 한다. 이를 위해 이미지 생성 후에 패키지 목록을 분석하거나, `oe-pkgdata-util`을 사용하여 패키지 데이터를 조사할 수 있다.

```sh
oe-pkgdata-util list-pkgs -r <이미지 이름>
```

<이미지 이름>을 통해 지정된 이미지의 패키지 목록을 출력하여 검토할 수 있다.

### 이미지 최적화

#### 불필요한 패키지 제거

**패키지 종속성 검사**: 패키지를 제거할 때, 해당 패키지가 다른 필수적인 패키지의 종속성이 아닌지 확인해야 한다. 이에 대한 종속성 분석 도구들을 활용할 수 있다.

**`bitbake-layers` 도구**: 이 도구는 종속성 트리를 작성하고 특정 패키지의 종속성을 보여준다.

```sh
bitbake-layers show-recipes <패키지명>
```

### 이미지 축소

이미지 크기를 줄이는 여러 방법이 있다. 다음은 몇 가지 주요 방법이다.

#### 사용하지 않는 기능 비활성화

1. **local.conf 조정**: 불필요한 기능을 비활성화하여 이미지 크기를 줄일 수 있다.

   ```sh
   DISTRO_FEATURES_remove = "x11"
   ```

   *e.g., x11 기능을 제거하여 불필요한 X Window System 관련 패키지를 제외할 수 있다.*
2. **busybox 사용**: busybox를 사용하여 여러 명령어를 하나의 바이너리로 통합하여 공간 절약이 가능한다.

   ```sh
   IMAGE_INSTALL_append = " busybox"
   ```

#### 압축 사용

이미지 파일 시스템을 압축하여 저장 공간을 절약할 수 있다. Yocto에서는 다양한 파일 시스템 및 압축 옵션을 지원한다.

1. **SquashFS**: SquashFS는 읽기 전용 파일 시스템으로, 높은 압축률을 제공한다.

   ```sh
   IMAGE_FSTYPES = "squashfs"
   ```
2. **Btrfs**: Btrfs는 고급 기능과 더불어 압축을 제공하는 파일 시스템이다.

   ```sh
   IMAGE_FSTYPES += "btrfs"
   ```

#### 최소화 레시피 사용

최대한 작은 이미지를 만들기 위해 최소화 레시피 최소화 모드(minimal mode)를 사용하거나 자체적으로 최소화된 레시피를 구성할 수 있다.

```sh
DISTRO ?= "poky-tiny"
```

**Poky-tiny**와 같은 경량화 분포판을 활용하여 작은 이미지 생성이 가능한다.

#### 패키지 관리 최적화

필요한 패키지들을 `packagegroup`을 통해 그룹화하여 관리하고, 한 번의 정의로 쉽게 패키지를 추가/제거할 수 있다.

1. **packagegroup**:

   ```bb
   SUMMARY = "Custom package group"
   DESCRIPTION = "Custom package group containing essential tools"
   RDEPENDS_${PN} = "nano wget curl"
   ```

   *packagegroup-mygroup.bb 파일을 예시로 RDEPENDS 변수를 사용하여 종속 패키지를 정의할 수 있다.*
2. **인덱스 재구성**: 이미지의 인덱스를 재구성하여 로딩 속도와 크기를 최적화할 수 있다.

   ```sh
   bitbake package-index
   ```

#### 디버그 정보 제거

디버그 정보를 제거하여 이미지 크기를 줄일 수 있다. 최종 이미지에서는 디버그 심벌을 제거하고 불필요한 파일을 삭제해야 한다.

```sh
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
```

이 옵션을 사용하면 디버그 정보가 포함된 패키지 형태로 분리되지 않으며, 최종 이미지에서 디버그 정보가 제거 된다.

### 결과 검토 및 배포

### 결과 검토

이미지를 생성한 후에는 다음과 같은 방법으로 검토할 수 있다.

1. **이미지 검사**: 생성된 이미지를 실제 하드웨어나 가상 머신에 배포하여 확인한다.
2. **패키지 목록 확인**:

   ```sh
   oe-pkgdata-util list-pkgs -r <이미지 이름>
   ```

**패키지 종속성 및 충돌 확인**: Yocto의 빌드 로그와 출력 패키지 데이터를 통해 종속성 문제와 충돌 여부를 확인한다.

### 배포

최종 이미지를 검토한 후에는 각 타겟 디바이스에 배포한다. 일반적으로 다음과 같은 방법을 사용한다:

1. **SD 카드 플래싱**: SD 카드나 기타 저장 매체에 이미지를 플래시하여 디바이스에 삽입한다.
2. **네트워크 배포**: TFTP 또는 NFS를 통해 네트워크로 이미지를 디바이스에 배포한다.
3. **OTG USB 플래싱**: USB OTG를 활용하여 디바이스에 직접 이미지를 전송한다.
