서론
아래 인용한 부분에 물리주소/가상주소 변환 공식이 나옵니다.
이 공식을 바탕으로 소설을 한 번 써 보겠습니다.
PHYS_OFFSET은 exynos5 가 사용하는 0x4000_0000 으로 정하겠습니다.
인용: Documentation/arm/Porting
Initial definitions
-------------------
The following symbol definitions rely on you knowing the translation that __virt_to_phys() does for your machine. This macro converts the passed virtual address to a physical address. Normally, it is simply:
phys = virt - PAGE_OFFSET + PHYS_OFFSET
소설1. 커널이 사용하는 물리 메모리 주소 범위
가상주소 3G (0xC000_0000) 부터 4G(0xFFFF_FFFF)까지는 커널이 사용하는 가상 메모리 영역입니다.
이 영역은 가상메모리와 물리메모리가 1:1 맵핑됩니다.
따라서 위 공식으로 주소를 변환할 수 있습니다.
물리주소의 시작:
phys = 0xC000_0000 - 0xC000_0000 (PAGE_OFFSET) + 0x4000_0000(PHYS_OFFSET)
phys = 0x4000_0000
물리주소의 끝:
phys = 0xFFFF_FFFF - 0xC000_0000 (PAGE_OFFSET) + 0x4000_0000(PHYS_OFFSET)
phys = 0x7FFF_FFFF
소설2. 부트로더가 zImage를 로드하는 주소
부트로더가 가상주소인 0xC000_8000에 zImage를 로드하므로 이 공식에 대입해 봅니다.
zImage가 로드되는 물리주소:
phys = 0xC000_8000 - 0xC000_0000 (PAGE_OFFSET) + 0x4000_0000(PHYS_OFFSET)
phys = 0x4000_8000
결론
- 커널이 사용하는 물리 메모리 영역은 0x4000_0000 부터 0x7FFF_FFFF 이다.- 부트로더가 zImage를 로드하는 물리 메모리 주소는 0x4000_8000이다.
- 그러므로 arch/arm/boot/compressed/head.S는 이 영역 안에서 모든 작업을 한다.
결론을 올바르게 도출한게 맞나요? ^^
댓글 3
-
tp
2013.07.30 17:36
-
리누즈박
2013.07.31 01:30
> 적어도 ARM에서는 소설2는 그야말로 소설로 보입니다.
> uboot은 MMU를 on하지 않습니다.
> 또한 Documentation/arm/Booting을 참조하면
> bootloader에서 zimage로 제어권을 넘길때 전제 조건이 mmu 및 cache off입니다.
소개해 주신 문서가 정말 많은 도움이 되었습니다.
> 또한 zImage에서 사용하는 mmu table은 physical address = virtual address로 설정합니다.
이 말은 무슨 말인지 이해가 되지 않는데.. 쉽게 설명해 주실 수 있나요?
> 물론 일부 bootloader의 경우 mmu를 켜고 사용하는 경우도 있겠으나 그 부트로더가 위에서 얘기된
> PAGE_OFFSET등을 똑같이 사용하리란 보장이 없지요.
> bootloader는 시스템의 memory map를 알고 있으므로 아무 address에(어떤 경우는 ROM에서도!!!)
> zImage를 위치시키고 실행할 수 있습니다. 이것이 zImage를 relocate가능하게 작성하는 이유입니다.
>
> 참고로 grep결과 __virt_to_phys()는 kernel(Image에 해당하는) 코드에서만 사용하고 있습니다. (zImage의 head.S와 무관함을 증명)
> 이 사실에 견주어 볼 때 x86등 다른 architecture 등도 비슷할 것 같습니다.
tp님의 댓글을 보고 2개의 u-boot를 까 보았습니다.
하나는 Samsung s3c6410(이하 6410)용이고
다른 하나는 Samsung Exynos4412(이하 4412)용입니다.
6410용 u-boot 코드에서는 0xC000_8000에 zImage를 로드하고 있었습니다. 아마도 MMU를 사용하는가 봅니다. 그 이유는 6410의 DRAM영역은 0x5000_0000 ~0x6FFF_FFFF 이기 때문이고 용량은 최대 512MB까지 지원합니다. 또한 0xC000_0000번지는 s3c410 User Manual의 메모리맵에는 존재하지 않는 주소입니다.
4412용 u-boot는 0x4000_8000 번지에 zImage를 로드합니다. 이건 물리주소네요. 4412의 DRAM영역은 0x4000_0000 ~ 0xFFFF_FFFF 입니다. 용량은 신품이라 그런지 3G까지 지원하는군요. 6410은 쨉도 안됩니다.
그렇다면 6410은 Documentation/arm/Booting의 전제조건인 mum및 cache off에 위배되는데 이건 어떻게 된 것일까요?
헉.. 벌써 잘 시간입니다. 내일 다시 시작해 보도록 하죠.
마지막으로 u-boot소스코드를 grep한 결과중 일부입니다. 있긴 있는데 s3c24x0만 쓰는 것 같습니다.
arch/arm/include/asm/arch-s3c24x0/memory.h #define PAGE_OFFSET (0xc0000000UL)
arch/arm/include/asm/arch-s3c24x0/memory.h:#define __virt_to_phys(x) ( (x) - PAGE_OFFSET + 0x0c000000 )
arch/arm/include/asm/arch-s3c24x0/memory.h:#define __phys_to_virt(x) ( (x) - 0x0c000000 + PAGE_OFFSET )
-
tp
2013.07.31 07:31
답글이 잘못되어 혼란이 있었습니다.
bootloader의 mmu 사용 여부는 case by case입니다.
uboot이 항상 mmu를 사용하지 않는 것처럼 설명한 것은 제가 틀렸습니다. 선택의 문제입니다.
사실 이미 arch/arm/boot/compressed/head.s에서 하고 있는 짓인데 어려울 것도 없지요.
(제 주변 SW엔지니어가 매번 uboot porting을 mmu off로 해서 저도 단정적으로 표현했네요.)
다만 kernel에 제어권을 넘기기 전에 반드시 mmu,cache를 off해줘야 합니다.
(사실 이 부분에 대해서는 최적환 관점에서 스토리가 좀 있습니다.)
physical address = virtual address란 말은 위의 c코드 수준으로 표현 해드린다면
#define __virt_to_phys(x) (x)
란 말입니다. zImage란 표현을 쓴 것은 arch/arm/boot/compressed/head.s에서 사용하는 mmu_table을
지칭하기 위해서 입니다.
arch/arm/boot/compressed/head.s의 mmu_table 설정 부분을 자세히 보시면 address가 바뀌지 않고 있습니다.
mmu를 가상 주소 mapping이 아닌 영역별 cacheability 제어를 위해 사용하기 때문에 address mapping을 바꿀 필요가 없습니다.
.
적어도 ARM에서는 소설2는 그야말로 소설로 보입니다.
uboot은 MMU를 on하지 않습니다.
또한 Documentation/arm/Booting을 참조하면
bootloader에서 zimage로 제어권을 넘길때 전제 조건이 mmu 및 cache off입니다.
또한 zImage에서 사용하는 mmu table은 physical address = virtual address로 설정합니다.
물론 일부 bootloader의 경우 mmu를 켜고 사용하는 경우도 있겠으나 그 부트로더가 위에서 얘기된
PAGE_OFFSET등을 똑같이 사용하리란 보장이 없지요.
bootloader는 시스템의 memory map를 알고 있으므로 아무 address에(어떤 경우는 ROM에서도!!!)
zImage를 위치시키고 실행할 수 있습니다. 이것이 zImage를 relocate가능하게 작성하는 이유입니다.
참고로 grep결과 __virt_to_phys()는 kernel(Image에 해당하는) 코드에서만 사용하고 있습니다. (zImage의 head.S와 무관함을 증명) 이 사실에 견주어 볼 때 x86등 다른 architecture 등도 비슷할 것 같습니다.