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 가 달랐다.
- 즉, uboot 은 env crc check 할때 image 의 크기만큼 읽어서 crc 체크를 하게된다. 하지만,
예제로 살펴보자. (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 값들과 연동되도록 제공될것이다.
...
휴휴 해당이슈로 한참을 개삽질을 한참을 했다;; 다른사람들에게 도움이 되길 바라며.. 끗.