SW 개발

[uboot] Warning - bad CRC, using default environment 에러 발생에 대한 고찰

. . . 2020. 3. 20. 18:05
반응형

uboot 관련 개발시 문제가 발생한내용을 디버깅한다.

문제 증상

uboot 부팅시 다음과같은 메시지가 발생한다.

Loading Environment from MMC... *** Warning - bad CRC, using default environment

말그대로, 영역의 저장된 env setting 파일을 읽었으나(혹은 읽지 못하여) 에러가 발생, 기본 hard coding 된 uboot env 를 사용 한다는것이다.

해당 로그가 발생하더라도, 기본 환경을 강제 로드하기 때문에 동작상에는 큰 문제는 없다.

문제원인들

문제원인 1 : 실제 env 영역 깨짐

구글링한 결과들을 보면, 지정된 uboot 의 flash 영역이 초기화가 안되거나, align 등이 맞지않거나 할경우 발생할 수 있다.

이러한경우, uboot 쉘에서 savee 명령을 통해서, 환경변수를 저장하더라도 저장이 되지 않는다. (계속적으로 CRC 에러가 나거나 아예 저장할수없다고 에러가 발생한다.)

해결책 : uboot env 영역을 uboot 에서 정상적으로 접근가능한지 확인해보자.

문제원인 2 : env 영역없음

실제 env 가 없는경우 발생한다. 이미지를 만드는과정에서 env image 가 env address 영역에 정상적으로 구어지지 않아서 발생 할 수 있다.

이러한경우, uboot 쉘상에서 savee 명령을 통해서, 환경변수를 정상 저장시 다음부팅서부터는 나타나지 않는다.

해결책 : image 를 만드는 스크립트에서 uboot env 를 write 하는 부분을 살펴보자. (임베디드 환경의경우 dd 명령어를 통해서 raw data 를 쓰게된다.)

다음과같이 되어있는 부분이 있을것이므로 살펴보자.

dd if=${uboot_env.env} of=${target_blk_device} bs=${blk_size} count=1

env 영역확인하기

env 영역의 주소를 알고있다면, 만들어진 이미지를 다음과 같은 명령어로 직접 hexdump 를 뜨면 된다.

hexdump -C -s ${env_영역주소} ./${이미지파일} | head -n 1000

리눅스가 부팅된 타겟보드에서는 다음과 같은 명령어로도 확인이 가능하다.

hexdump  -C -s ${env_영역주소} /dev/mmcblk0 | head -n 1000

문제원인 3 : env crc 안맞음 (mkenvimage 명령어관련)

env image 는 제대로 구어졌으나, image 의 crc 가 맞지 않아서 발생하기도한다.

이때의 대부분의 이슈는 mkenvimage 명령어의 인자가 달라서 그렇다.

  • 필자의 경우 mkenvimage 명령어 스크립트에서 주어지는 image size 인자와 실제 env image 의 크기가 달라서 문제가 발생했다.
    • 즉, uboot 은 env crc check 할때 image 의 크기만큼 읽어서 crc 체크를 하게된다. 하지만, mkenvimage 명령어에서 주어진 image size 가 다르다보니 만들어진 crc checksum value 가 달랐다.

예제로 살펴보자. (BSP 에 다음과같은 라인이 있을것이다.아마 다음과 같은 멸)

mkenvimage -s ${BOOTENV_SIZE} -r -o ${WORKDIR}/uboot.env ${WORKDIR}/${U_BOOT_ENV_TXT}
  • ${BOOTENV_SIZE} : boot env image size

테스트를위해서... 위의 명령어를 통해서 동일한 env image 를 만들자. 이때, ${BOOTENV_SIZE} 인자를 수정하여 각각의 image 를 만들어보자. 위의 명령어를 통해서 만들어진, 각각의 uboot.env 파일을 hexdump 명령어를 통해서 살펴보면..

hexdump -C ./uboot.env
00000000  9b 20 56 29 01 61 6c 74  62 6f 6f 74 63 6d 64 3d  |. V).altbootcmd=|
00000010  72 75 6e 20 6d 65 6e 64  65 72 5f 61 6c 74 62 6f  |run mender_altbo|

- CRC 부분 : 9b 20 56
hexdump -C ./uboot.env
00000000  91 c1 d7 32 01 61 6c 74  62 6f 6f 74 63 6d 64 3d  |...2.altbootcmd=|
00000010  72 75 6e 20 6d 65 6e 64  65 72 5f 61 6c 74 62 6f  |run mender_altbo|

- CRC 부분 : 91 c1 d7

동일한 내용의 env image 가 각각 만들어지지만, image 의 크기는 달랐다. 특이한점은 image 의 크기에 따라 앞의 3바이트가 각각 다르다는점이다. 즉, uboot 에서 CRC 체크할때 env image 의 전 영역을 CRC 체크한다는것이다. 고로... env image size 또한 기존에 define 된 값과 맞아야한다는 점이다.

참고사항

간혹 구글링을 하다보면, uboot 에서 다음과같이 feature를 처리하면된다고들 하는답변들이 있다.

# - disable CONFIG_ENV_IS_IN_FAT
# - enable CONFIG_ENV_IS_NOWHERE

필자가 테스트해본결과 위의 환경설정이 직접접적인 원인은 아닌것 같다. 일단 위의 원인부터 살펴보자.

UBOOT 에서의 env image / env setting 주소, 크기관련

uboot 에서 env 영역과, 해당 image 사이즈 설정은 ./include/configs/보드명.h 에 다음과 같이 정의 되어 있다.

#define CONFIG_ENV_SIZE         (0x2000)
#define CONFIG_ENV_OFFSET       (0xD0000)

보드마다 위의 설정은 다를것이다.

대부분 칩사에서 제공되는 BSP 에서는 mkenvimage, dd 명령어 사용시에 위의 define 값들과 연동되도록 제공될것이다.

...

휴휴 해당이슈로 한참을 개삽질을 한참을 했다;; 다른사람들에게 도움이 되길 바라며.. 끗.

반응형