포고플러그 프로/V3에 데비안 등 리눅스 배포판을 설치하기 위한 uboot 업그레이드 방법을 정리해본다.
자칫 벽돌이 될 수 있고, 완전한 순정으로 돌아갈 수 없으니 주의해야한다!!!


0. 배경 & 준비

- 호환 기기: Pogoplug V3, Pogoplug V3 Classic 등 OXNAS OX820 계열 기기

- 2015.10 버전 특징:
  NAND flash 없이 부팅디스크의 설정파일(uEnv.txt)을 이용해서 uboot env 수정 가능
  FDT and non-FDT kernel 모두 지원
  2TB 이상의 EFI/GPT 파티션 지원 (SATA and USB, 부팅 디스크로도 사용 가능)
  부팅 디스크에 Ext4 파일시스템 지원
  uboot 단계에서 NTP 지원 (SNTP)
  zImage 부팅
  Overclock (700 Mhz → 850 Mhz)

- 2015.10 버전 uboot은 850 Mhz로 오버클럭 설정되어있으며 (순정 700 Mhz), netconsole이 안된다. 오버클럭을 원치 않으면 구버전 2013 uboot에 포함된 SPL을 가져다 사용하고, netconsole이 필요하면 2013 uboot을 사용해야 한다.

- 참고 및 uboot 배포 링크: 2015.10 U-Boot for Pogoplug V3 (OXNAS OX820)

- uboot 유틸리티 관련 링크: U-Boot flashing utilities

- 상기 uboot 배포 링크에서 아래 파일을 찾아 다운받고 포고플러그로 옮겨두어야 한다. 포고플러그 상에서 wget으로 받으면 좋은데, 불행히도 원본 파일이 dropbox link라서 그게 안되더라. (포고플러그의 wget이 https 프로토콜을 지원하지 않는 듯 하다)

uboot.2015.10-tld-1.ox820.bodhi.tar
linux-tools-installation-bodhi.tar.gz

편의 상 현 시점 최신 버전을 티스토리에 올렸고 위 링크를 카피하여 wget으로 받으면 된다. 그러나 파일명은 깨진다. -O 옵션으로 파일명을 지정할 수 있다.

# cd /tmp

# wget -O uboot.2015.10-tld-1.ox820.bodhi.tar http://notme.tistory.com/attachment/cfile30.uf@99535C33598B10AD242FB7.tar

# wget -O linux-tools-installation-bodhi.tar.gz http://notme.tistory.com/attachment/cfile3.uf@99C2AA33598B25352DAF6D.gz

다운받은 파일을 아래와 같이 압축을 풀고, fw_printenv를 fw_setenv로 심볼릭 링크를 걸어준다.

# tar -xvf uboot.2015.10-tld-1.ox820.bodhi.tar
uboot.2015.10-tld-1.ox820.mtd0.img
uboot.spl.2013.10.ox820.850mhz.mtd0.img
uboot.2013.10-tld-5.ox820.environment
uboot.2013.10-tld-5.ox820.environment.img

# tar -xvzf linux-tools-installation-bodhi.tar.gz
tools/
tools/busybox
tools/e2fsck
tools/nanddump
tools/fw_printenv
tools/flash_erase
tools/nandwrite
tools/fw_env.config

# cd tools
# ln -s fw_printenv fw_setenv


1. 안전한 Flashing 및 사고 발생 시 대처를 위해 미리 확인해야할 것들

포고플러그에 ssh로 접속하여 아래 내용 확인

- MTD 정보 확인

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 08000000 00020000 "NAND 128MiB 3,3V 8-bit"
mtd1: 00e00000 00020000 "boot"
mtd2: 07200000 00020000 "rootfs"

참고 자료에는 boot와 rootfs 파티션만 있지만, 내 경우엔 파티션이 세개였다. 찬찬히 보니 mtd0가 NAND 전체이며, mtd0를 분할하여 mtd1, mtd2가 만들어져 있었다. uboot env를 수정하여 boot와 rootfs를 mtd0와 mtd1으로 재정의하라고 되어 있는데, 이해도 잘 안되고 귀찮아서 그냥 현재 파티션 구조를 그대로 유지하기로 했다. 덕분에 앞으로 사용하는 명령어의 내용이 참고 자료와는 조금 다르다.

참고로 상기 숫자는 16진수로 표시된 바이트 단위 용량이며, mtd1은 14 MiB, mtd2는 114 MiB, 기록단위는 128 KiB라는 것을 의미한다.


- /etc/fw_env.config

만약 상기 파일이 없을 경우 아래 내용대로 만들어주면 된다. 나중에 uboot env를 올리는 위치를 기록해두는 것으로 부팅 시 uboot이 env를 어디서 찾아야하는지 알려주는 것이다.

# MTD device name         Device offset   Env. size       Flash sector size
  /dev/mtd0               0x00100000      0x20000         0x20000

1 MiB 지점 부터 128 KiB 용량의 공간에 uboot env를 올리겠다는 의미.


- 백업

순정/구버전 uboot인 mtd1과 환경변수를 아래와 같이 백업한다.

# cd /
# /tmp/tools/nanddump --noecc --omitoob -f uboot.mtd1.org /dev/mtd1
# /usr/local/cloudengines/bin/blparam > uboot.env.org.txt

순정 uboot env의 내용은 아래와 같다.

bootcmd=run boot_nand
bootdelay=2
baudrate=115200
autoload=n
netmask=255.255.0.0
bootfile="uImage"
kernflmode=s
load_nand=nboot 60500000 0 200000
load_nand2=nboot 60500000 0 800000
boot=bootm 60500000
boot_nand=run load_nand boot || run load_nand2 boot
stdin=serial
stdout=serial
stderr=serial
bootargs=root=ubi0:rootfs ubi.mtd=2,512 rootfstype=ubifs console=ttyS0,115200 elevator=cfq mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01 mem=128M poweroutage=yes
ethaddr=00:25:31:??:??:??
cesvcid=??????????????????????????
ceboardver=PPRO1
serverip=192.168.33.2
ipaddr=192.168.33.195


- mtd0 내에 bad block이 있는지 확인

부팅 시 파일시스템 체크를 이미 했으므로, dmesg 명령으로 bad block이 있는지 확인할 수 있다. block 0~15 까지는 절대 bad block이 있을 경우 uboot을 올리면 안된다. 아래 내 포고플러그 프로의 경우는 97번 block이 bad block인데, 이건 상관이 없다.

# dmesg | grep -i 'bad'
<6>[    5.230000] Scanning device for bad blocks
<4>[    5.240000] Bad eraseblock 97 at 0x000000c20000


여기까지 진행한 확인사항, 백업파일 등을 포고플러그 밖으로 꺼내놓는 것이 좋다. 문제 발생 시 공부해야할 것이 참 많아지거든..



2. uboot, uboot env Flash

이 과정은 실수하면 벽돌이 된다. 오타 없이 주의해서 진행하자. 혹시나 에러 메시지가 출력될 경우 절대 전원을 끄지 않고, 해결 방법을 찾아보자.

- uboot 올리기

# /usr/sbin/flash_erase /dev/mtd1 0x0 6       :앞쪽 6블럭 삭제, SPL/uboot를 위한 공간 만들기
Erase Total 6 Units
Performing Flash Erase of length 131072 at offset 0xa0000 done

# /usr/sbin/nandwrite /dev/mtd1 /tmp/uboot.spl.2013.10.ox820.850mhz.mtd0.img       :SPL 쓰기
Writing data to block 0 at offset 0x0

# /usr/sbin/nandwrite -s 262144 /dev/mtd1 /tmp/uboot.2015.10-tld-1.ox820.mtd0.img :uboot쓰기
Writing data to block 2 at offset 0x40000
Writing data to block 3 at offset 0x60000
Writing data to block 4 at offset 0x80000
Writing data to block 5 at offset 0xa0000


- 기본 uboot env 올리기
/etc/fw_env.config 내용을 기억하자.

# /usr/sbin/flash_erase /dev/mtd1 0x00100000 1                : uboot env를 위한 공간 만들기
Erase Total 1 Units
Performing Flash Erase of length 131072 at offset 0x100000 done

# /usr/sbin/nandwrite -s 1048576 /dev/mtd1 /tmp/uboot.2013.10-tld-5.ox820.environment.img
: 기본 uboot env 쓰기

Writing data to block 8 at offset 0x100000



3. uboot env 맞춤 설정

- 하드웨어 관련: 아래는 포고플러그 프로 기준

# /tmp/tools/fw_setenv ethaddr '00:25:31:??:??:??' 
   : 포고플러그 내장 유선 랜카드, 기기 바닥에 적혀있음
# /tmp/tools/fw_setenv dtb_file '/boot/dts/ox820-pogoplug-pro.dtb'
   : 기본 uboot env는 이미 위 값이 들어있음. 무선랜이 없는 포고 V3 classic의 경우 ox820-pogoplug-classic.dtb


- 넷콘솔 관련

uEnv를 지원하는 uboot과 함께라면 거의 만능이 되는 netconsole 관련 설정. mtd0(uboot)이 깨지기 전까지는 시리얼 케이블과 거의 동일한 복구 능력을 발휘한다. 강추
넷콘솔 관련 참고 자료: Use netconsole to troubleshoot uBoot without a serial cable
단, 2015.10 버전은 넷콘솔이 안되니까 신경쓰지 말자. 이 경우 시리얼 케이블을 미리 사두는걸 추천한다.

# /tmp/tools/fw_setenv serverip '192.168.0.40'
   : 넷콘솔 서버 ip 지정. 리눅스 추천하며 브릿지 모드의 가상머신이라도 될 듯 함.
# /tmp/tools/fw_setenv ipaddr '192.168.0.26'
   : 포고플러그가 사용할 ip주소


- 잡것: 그다지 중요치 않은 선택사항

# /tmp/tools/fw_setenv bootdev 'usb'
   : 기본 부팅 디바이스인데, 실은 아래 devices 순서대로 uEnv.txt를 검색하고, uEnv.txt가 발견된 디바이스로 부팅해버리는 듯 하다. 즉.. bootdev는 의미가 없음..

# /tmp/tools/fw_setenv devices 'usb ide'
   :  uEnv.txt를 검색할 후보 device들. 기왕이면 부팅 디스크를 앞에 두는 것이 좋지만 워낙 검색 속도가 빨라 큰 의미를 두지 않아도 됨.

# /tmp/tools/fw_setenv disks '0 1 2 3 4'
   : devices에 지정된 디바이스를 각각 몇개씩 확인할지 결정. usb의 경우 0번 device가 hub인 듯 하여 1,2,3,4 번까지는 지정해두는 것이 좋겠다. 아무 usb port에 부팅 디스크를 삽입해도 부팅 가능하도록


- systemd 사용하기

systemd를 사용하려면 /boot/uEnv.txt에 아래 내용을 적어준다. 물론 systemd를 설치해줘야한다. 본 글에서는 부팅 디스크를 만들지 않았기 때문에 아직은 설정할 수 없다.

custom_params=init=/bin/systemd


미래를 위해서 여기까지 수정한 uboot env 내용을 텍스트로 백업해두자. 벽돌 복구할 때 유용하게 쓰인다. 포고플러그 밖으로 뺴 놓는 것 잊지 말고.. 순정 OS에서 작업했다면 리부팅 전에 기기 외부로 백업하는 것이 좋다.

# /tmp/tools/fw_printenv > /uboot.env.2017.08.10.txt

방금 만든 uboot env 텍스트 파일을 열어보았을 때 에러 메시지가 있으면 무언가 잘못된 것이고, 문제를 해결하지 않고 리부팅하면 벽돌이 된다.

여기까지 에러 없이 모두 정상이라면 무사히 uboot 업그레이드를 마친 것이다. 리부팅 하면 새 uboot이 반길 것이다. 물론 시리얼 케이블이나 새 uboot에 맞는 부팅 디스크가 없다면 무한 리부팅 되므로 벽돌이나 다름 없지만 말이다. ^^