Linux/buildroot

A/B 파티션을 이용한 안전한 업데이트 기법

임베디드 친구 2025. 5. 1. 22:30
728x90
반응형

A/B 파티션을 이용한 안전한 업데이트 기법

1. 개요

임베디드 시스템에서 Over-the-Air(OTA) 업데이트는 필수적인 기능입니다. 하지만 업데이트 과정에서 전원이 꺼지거나 오류가 발생하면 시스템이 손상될 수 있습니다. 이러한 문제를 방지하기 위해 A/B 파티션 업데이트 기법이 사용됩니다. 이 기법을 활용하면 새로운 펌웨어를 적용하기 전에 기존 펌웨어를 유지할 수 있어 안전한 업데이트가 가능합니다.

Buildroot 환경에서 A/B 파티션 업데이트를 구성하는 방법을 설명하며, 예제와 함께 적용하는 방법을 다룹니다.

2. A/B 파티션 업데이트 개념

A/B 파티션 업데이트는 두 개의 독립적인 파티션(A와 B)을 사용하여 업데이트를 수행하는 방식입니다. 하나의 파티션이 활성 상태(active)로 실행되고 있을 때, 다른 파티션에서 새로운 이미지를 업데이트할 수 있습니다. 업데이트가 성공적으로 완료되면 부트로더에서 새로운 파티션으로 부팅이 전환됩니다.

A/B 파티션 업데이트의 장점

  • 안정성 보장: 업데이트 중 문제가 발생해도 현재 실행 중인 파티션에 영향을 주지 않음
  • 빠른 롤백: 새로 업데이트된 이미지가 부팅에 실패하면 기존 파티션으로 복구 가능
  • 다운타임 최소화: 실행 중인 파티션에서 새로운 이미지를 설치하여 업데이트 시간을 최소화함

A/B 파티션 구성 예시

파티션 역할
A 현재 실행 중인 OS
B 업데이트를 위한 대기 OS
Bootloader 부트 프로세스 관리
Data 사용자 데이터 보관

3. Buildroot에서 A/B 파티션 설정

Buildroot를 이용하여 A/B 파티션 업데이트를 구현하려면 다음과 같은 과정이 필요합니다.

3.1. 파티션 테이블 구성

Buildroot에서 A/B 파티션을 사용하려면 fdisk 또는 parted를 이용하여 적절한 파티션을 구성해야 합니다. 예제는 아래와 같습니다.

parted /dev/mmcblk0 --script mklabel gpt
parted /dev/mmcblk0 --script mkpart primary ext4 1MiB 500MiB
parted /dev/mmcblk0 --script mkpart primary ext4 500MiB 1000MiB
parted /dev/mmcblk0 --script mkpart primary ext4 1000MiB 1100MiB
parted /dev/mmcblk0 --script mkpart primary ext4 1100MiB 2000MiB

위 설정에서:

  • /dev/mmcblk0p1: A 파티션 (현재 실행 중인 OS)
  • /dev/mmcblk0p2: B 파티션 (대기 OS)
  • /dev/mmcblk0p3: Bootloader
  • /dev/mmcblk0p4: Data 파티션

3.2. 부트로더 설정

A/B 업데이트를 지원하는 부트로더(U-Boot)를 설정해야 합니다. fw_setenv를 이용하여 현재 활성화된 파티션 정보를 저장할 수 있습니다.

U-Boot 환경 변수 설정

fw_setenv upgrade_available 0
fw_setenv boot_partition A

부팅할 파티션을 변경하려면 다음 명령을 실행합니다.

fw_setenv boot_partition B
reboot

3.3. 업데이트 스크립트 구현

업데이트 프로세스를 자동화하기 위해 스크립트를 작성할 수 있습니다. 예제는 다음과 같습니다.

update.sh

#!/bin/sh

# 현재 활성화된 파티션 확인
CURRENT_PART=$(fw_printenv boot_partition | cut -d '=' -f2)

if [ "$CURRENT_PART" = "A" ]; then
    TARGET_PART="/dev/mmcblk0p2"
    NEW_PART="B"
else
    TARGET_PART="/dev/mmcblk0p1"
    NEW_PART="A"
fi

echo "업데이트를 $NEW_PART 파티션으로 진행합니다."

# 새 이미지 다운로드 및 설치
wget -O /tmp/update.img http://example.com/update.img

dd if=/tmp/update.img of=$TARGET_PART bs=4M
sync

# 부팅 파티션 변경
fw_setenv boot_partition $NEW_PART
fw_setenv upgrade_available 1
reboot

이 스크립트는 현재 활성화된 파티션을 확인한 후, 다른 파티션에 새 이미지를 다운로드하여 설치하고, 부팅 파티션을 변경하는 방식으로 동작합니다.

4. 롤백 메커니즘

새롭게 업데이트된 파티션에서 부팅이 실패할 경우 롤백할 수 있어야 합니다. 이를 위해 watchdog 및 부트 카운터를 활용할 수 있습니다.

U-Boot에서 부팅 실패 감지

U-Boot 환경 변수에 부팅 횟수를 기록하고, 특정 횟수 이상 실패하면 이전 파티션으로 복구하는 방법을 사용할 수 있습니다.

fw_setenv boot_try_count 0

부팅 시마다 스크립트에서 boot_try_count를 증가시키고, 특정 횟수(예: 3회) 이상 실패하면 롤백하도록 설정합니다.

if [ "$boot_try_count" -ge 3 ]; then
    if [ "$boot_partition" = "A" ]; then
        fw_setenv boot_partition B
    else
        fw_setenv boot_partition A
    fi
    fw_setenv boot_try_count 0
    reboot
fi

5. 결론

A/B 파티션을 활용한 OTA 업데이트 방식은 시스템을 안전하게 업데이트할 수 있는 효과적인 방법입니다. 이를 통해 업데이트 중 발생할 수 있는 실패 상황에서도 장치를 보호할 수 있으며, 원활한 롤백을 통해 운영 안정성을 높일 수 있습니다.

Buildroot 환경에서 A/B 파티션을 구성하는 방법을 숙지하고, 실제 환경에서 적용할 수 있도록 구성하는 것이 중요합니다. 본 가이드에서 제시한 예제 코드를 바탕으로 실험을 진행하고, 부트로더 및 업데이트 스크립트를 환경에 맞게 수정하여 활용하시기 바랍니다.

반응형