Skip to content
isdnetworks
Go back

패키지 하나에 보드가 둘이었다

장비 펌웨어 업그레이드 패키지를 받아서 풀어 봤다.

runme.sh
ubi_info
c5/
  angstrom_rootfs.jffs2
  soc_system.rbf
  upgrade-marker.bin
xilinx/
  BOOT.bin
  devicetree.dtb
  uImage
  rootfs.jffs2
  upgrade-marker.bin

폴더가 둘이다.

Table of contents

Open Table of contents

같은 제품인데 보드가 둘이다

c5xilinx 는 서로 다른 제어 보드용이다. 같은 제품인데 생산 시기에 따라 들어간 보드가 다르다.

초기 물량에 들어간 보드와 후기 물량에 들어간 보드가 따로 있고 각각 펌웨어가 다르다. 겉모양과 제품 이름은 같으니 밖에서는 구분이 안 된다.

한 패키지에 두 벌을 담은 것이 처음에는 이상해 보였는데 배포 쪽에서 보면 그 반대다. 가르는 순간 받는 쪽이 자기 보드를 알아야 한다.

하나로 묶은 이유

패키지를 둘로 나누는 것도 가능하기는 하다.

[나누면]  사용자가 자기 보드를 알아야 함
[합치면]  아무거나 받아도 됨

문제는 사용자가 자기 보드를 모른다는 점이다. 케이스를 열어 봐야 아는 것을 물어보는 것은 무리다.

잘못 고르면 장비가 안 뜨는데 그 판단을 사용자에게 맡길 수 없다. 그래서 합치는 쪽이 맞아 보인다.

전체 흐름 — 판정 순서

합치면 그다음은 스크립트가 판정해야 한다. runme.sh 를 열어 봤다.

if [ -e /usr/bin/ctrl_bd ]; then
    ret=`cat /usr/bin/ctrl_bd | grep "XILINX" | wc -l`
else
    ret=0
fi

if [ $ret -eq 1 ]; then
    cd ./xilinx
    ...

/usr/bin/ctrl_bd 라는 제어 바이너리를 cat 해서 XILINX 문자열이 있는지를 센다. 그 수가 1이면 xilinx 폴더로 들어간다.

바이너리에서 문자열을 찾는다

이 방법이 흥미로웠다. 실행 파일 안에 보드 이름이 문자열로 들어 있고 그것을 grep 으로 찾는다.

실행 파일 안에 보드 이름이 문자열로 들어 있음

grep 으로 찾음

있으면 그 보드

바이너리를 텍스트처럼 다루는 셈이다. 더 나은 자리가 있었을 것 같은데 셋 다 없었던 모양이다.

[설정 파일]      보드 이름이 적힌 파일 — 있으면 그걸 읽음
[장치 노드]      /proc, /sys 에서 확인
[전용 명령]      보드 정보를 출력하는 명령

있는 것으로 판정하려니 바이너리 grep 이 남은 것으로 보인다.

주의 — 우연한 조건에 기댄 판정

이 방식이 성립하려면 조건 셋이 동시에 유지돼야 한다.

그 바이너리 이름이 바뀌면 안 됨
그 문자열이 사라지면 안 됨
다른 보드 바이너리에 그 문자열이 없어야 함

셋 다 코드가 보장하는 것이 아니라 그렇게 돼 있을 뿐이다. ctrl_bd 의 경로가 바뀌거나 빌드 설정이 달라져 그 문자열이 빠지면 판정이 뒤집힌다.

판정 근거가 우연이면 그 근거가 언제 사라지는지를 아무도 모른다. 보드마다 식별 값을 한 자리에 두고 그것을 읽는 쪽이 안전해 보인다.

판정 실패 시의 기본값

ctrl_bd 가 없을 때의 처리가 위에 함께 있다.

if [ -e /usr/bin/ctrl_bd ]; then
    ret=`...`
else
    ret=0
fi

파일이 없으면 ret 가 0이고 그러면 다른 보드 쪽으로 간다. 판정에 실패해도 설치는 그대로 진행된다는 뜻이다.

[안전한 기본값]  판정 실패 시 아무것도 안 함
[이 스크립트]    판정 실패 시 다른 쪽을 씀

플래시에 잘못된 이미지를 쓰면 장비가 안 뜨므로 멈추는 쪽이 안전해 보인다. 다만 그러면 판정이 조금만 어긋나도 아무도 업그레이드를 못 하게 된다.

어느 쪽 위험을 안을지의 문제로 보인다. 현장에서 벽돌이 되는 쪽과 아무도 못 올리는 쪽 중 어느 것이 덜 나쁜지는 그 제품의 사정이 정할 일이다.

두 보드는 부팅 구조가 다르다

두 폴더의 파일 목록도 달랐다.

A 보드   rootfs, FPGA 비트스트림, 업그레이드 마커
B 보드   BOOT, 디바이스트리, 커널, rootfs, 업그레이드 마커

xilinx 쪽에는 BOOT.bindevicetree.dtbuImage 가 있다. 부트로더가 커널을 올리고 커널이 rootfs 를 잡는 흐름이다.

c5 쪽에는 그 대신 soc_system.rbf 가 있다. FPGA 설정 파일이라 회로 구성부터 시작하는 셈이다.

겉으로는 같은 제품인데 안쪽은 아키텍처가 다르다. 그 둘을 패키지 하나가 다 받아 준다.

양쪽에 upgrade-marker.bin 이 함께 있는 것도 눈에 띈다. 플래시 특정 자리에 표시를 남겨서 다음에 이미 했는지를 확인하려는 것으로 보인다.

사람이 읽는 메모가 들어 있다

패키지에 ubi_info 라는 파일이 하나 더 있었다. 열어 보니 한 줄이었다.

only for this update 2 ubi package

스크립트가 읽는 값이 아니라 사람이 읽는 메모다. 파싱해서 쓰는 것과 읽어 보라고 넣은 것이 한 패키지에 섞여 있다.

이 방식이 나쁘지 않아 보였다. 패키지가 여러 벌 돌아다니면 어느 것이 무엇인지 헷갈리는데 파일명은 옮기고 다시 압축하는 사이에 바뀐다.

안에 넣어 두면 안 바뀐다. 문서 안쪽에 갱신 일자를 적어 두는 것과 같은 이유로 보인다.

정리


Share this post on:

Previous Post
한 대만 보고 판단했다
Next Post
정상 종료가 오류로 기록됐다