바이너리/헥스 덤프에서 U-Boot 환경의 위치를 ​​알아내는 과정

바이너리/헥스 덤프에서 U-Boot 환경의 위치를 ​​알아내는 과정

간단히 말해서:

u-boot가 활성화된 보드(버전 1.6.1)가 있고 dd를 사용하여 환경 변수가 포함된 파티션을 바이너리 파일로 덤프했습니다. 이제 발견된 파티션의 위치를 ​​변환하는 방법을 찾는 데 어려움을 겪고 있습니다. ASCII 값을 OFFSET 및 fw_env로 .config의 SIZE 매개변수로 지정합니다. (숫자를 찾고 시도하는 다른 방법도 실패합니다.)

나는 여기에서 모든 유형의 시스템에서 이 작업을 수행하고 첫 번째 ASCII 매개변수 주소를 간단히 복사하여 붙여넣는 것이 작동하지 않기 때문에 무엇을 추가하거나 빼거나 이동해야 하는지 말해 줄 수 있는 사람을 찾고 싶습니다.

전체 기록(TLDR에서 가장 관련성이 높은 정보 확장, "가장 관련성 있는" 제목 뒤에 긴 서문이 "이전 노력에 대한 평가"이며 완전함):


저는 어려운 문제에 직면해 있으며 주말 내내 검색하고 노력했지만 아직 해결책을 찾지 못했습니다.

U-boot-1.6.1의 수정된 버전을 실행하는 삼성 ARM 기반 Linux 임베디드 시스템을 "상속"했습니다. 저는 몇 가지 버그를 수정하는 임무를 맡았는데, 그 중 하나는 환경 변수를 u-boot로 업데이트해야 합니다.

문제의 시스템은 EmbedSky 보드, 특히 TQ2440입니다. 이는 잘 알려진 유형이 아니고 중국/홍콩에서 나온 것 같아서 별로 도움이 되지 않습니다.

fw_printenv/fw_setenv를 성공적으로 컴파일했습니다.이런 가이드를 사용하세요그리고 사용된 u-boot의 소스 파일을 얻었습니다.

특히 나중에 참조할 수 있도록 몇 가지 더듬거리고 재촉한 후에 PC 기반 빌드 환경에서 도구에 대한 완전한 호출 결과는 다음과 같습니다(u-boot 루트 폴더 내).
make env ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- HOSTCC=arm-none-linux-gnueabi-gcc
마지막 토큰은 버그인 것으로 보입니다. 2012년에는 여전히 다소 논란의 여지가 있지만 makefile이 env 도구의 HOSTCC용으로 컴파일되기 때문에 필요합니다. EmbedSky의 2015년 버전을 수정하려는 시도가 매우 잘못되어(모든 종류의 누락된 항목) 포기했기 때문에 이것이 2014/2015 버전에서도 여전히 해당되는지는 모르겠습니다.

이제 내 문제는 EmbedSky.h에 다음 정의가 나타난다는 것입니다(CONFIG_는 발견되지 않고 CFG_만 발견됨).

#define CFG_ENV_SIZE    0x020000
#define CFG_ENV_OFFSET  0x1F0000

/proc/mtd에서는 mtd0의 이름이 "uboot", mtd1의 이름이 "kernel", mtd2의 이름이 "root"임을 보여주지만 다른 mtd 섹터는 존재하지 않습니다.
여기서 "uboot"가 포함된 mtd0은 0x40000길고, 블록 크기는 이고 0x20000, 삭제 크기는 이므로 오프셋 0x20000에 맞지 않습니다 .0x1F0000

일치하는 한 가지는 mtd0 "uboot" 장치가 NAND 플래시에 있고 EmbedSky.h 파일의 모든 구성 매개변수가 NAND 플래시에 적용된다는 것입니다.

물론 완고한 작은 일꾼으로서fw_env.config 파일을 설정해 보았습니다.세 개의 mtd 파티션 모두에 알려진 숫자의 모든 조합. 오프셋과 함께 fw_printenv를 호출하면 0x1F0000"잘못된 명령"과 같은 오류가 발생하고 아래에서 시도하는 모든 작업에는 "CRC 오류: 기본 환경 사용"이 표시됩니다.
(위 링크에 여전히 HOSTCC= 지시어가 포함되어 있다는 것을 알았습니다 :-))

여기서 각 조합은 다음을 의미합니다. OFFSET=0x00000; 오프셋 중간, 오프셋 1 섹터 안쪽, 오프셋 2 섹터, 크기는 각각 0x04000 및 0x20000, 범위는 1입니다. 2 또는 3개 부문. 그래서 사실이 아니야모든, 그러나 특히 크기의 경우 이는 제가 찾은 튜토리얼과 헤더 파일에서 본 모든 숫자입니다.

이 시점에서 나는 내가 가지고 있는 리소스가 프로젝트의 나머지 부분에 적합하기 때문에 실제로 보드에 있는 리소스가 아닐 수도 있다고 생각합니다. 그래서 다른 방법을 찾아봤습니다.

오늘 밤 3시경에 "u-boot 환경이 포함된 mtd를 덤프한 다음 기본 및 중복 블록을 살펴보는 것"에 대한 블로그 게시물을 보았습니다. 혼란스러운 자정 상태에서 방금 Google을 다시 검색했습니다. 북마크하기 전에 페이지를 방문했는데 블로그를 다시 찾을 수 없는 것 같습니다.

가장 관련성이 높은 것:

그래서 나는 희망을 가지고 달려가 sudo dd if=/dev/mtd0 of=/home/ActiveMtd0.bin bs=128k count=2정보를 내 /proc/mtd 목록에 넣었습니다. 결과: 256kbyte가 복사되었습니다.

이것은 나에게 바이너리 파일을 제공하며, 보라, 여기에는 순수 ASCII 형식의 u-boot 환경 변수가 포함되어 있습니다. 환호! 그러나 아쉽게도 이 모든 "명백함"이 나를 좌절시키는 것 같습니다. 첫째, 이 덤프에는 중복 블록이 아닌 하나의 블록만 포함되어 있으므로 트릭이 사라집니다. 둘째, 블록의 시작 부분 0x367F8(아마도 CRC의 4바이트 뒤에 첫 번째 ASCII 매개변수가 오는 부분)이 내가 상상할 수 있는 모든 아키텍처의 편리한 셀 경계와는 거리가 먼 것 같습니다. 0 패딩으로 488바이트 이상 실행됩니다. 여기서 env 다음의 0이 아닌 첫 번째 바이트는 이며 0x369B8, 이는 또한 좋은 위치가 아닙니다. 두 지점 모두 8바이트로 정렬되므로 최소한 그게 전부입니다. 이것이 관련이 있든 없든 추측만 할 수 있습니다.

0x367F8낙관적으로 나는 크기(=488 십진수)의 구성 파일에서 mtd0에 OFFSET =을 시도했지만 0x01C0블록 크기, mtd0의 경계를 넘어서는 등의 이유로 잘못된 지침도 제공했지만 이것은 훨씬 더 자세합니다. 내부 u-boot fw_printenv 프로세스에 대해 내가 아는 것보다. 그런 다음 OFFSET= 0x367FC및 SIZE=를 시도하여 0x01BC첫 번째 변수의 첫 번째 문자에 설정하고 CRC라고 생각한 부분을 건너뛰었지만 그것도 실패했습니다. env의 ascii 값은 488바이트보다 훨씬 작으며 후반부는 0 패딩이라는 점에 유의해야 합니다. 이것이 프로세스와 관련이 있는지는 알 수 없습니다.

나는 지금 완전히 당황했습니다.

누구든지 바이너리 mtd0 덤프의 이 지점에서 "이것에서 12바이트 빼기" 또는 "4로 나누기"에 대해 말해 줄 수 있습니까? 나는 스크립트 파일에서 직접 NAND 플래시를 방해하는 것보다 현장에서 수백 개의 장치를 자동화하는 것이 더 안전하기 때문에 fw_printenv 및 fw_setenv를 사용하는 것을 정말 좋아합니다.

"당신이 시도한 주소 중 하나가 올바른 주소여야 합니다."라고 하더라도 지금은 겉보기에 임의의 숫자를 사용하여 어둠 속에서 촬영하고 있는 것처럼 느껴지기 때문입니다. 대부분의 숫자 뒤에는 어떤 이유가 있음에도 불구하고 말입니다.

관련 정보