ARM linux 커널을 시작할 때 몇 개의 키 주소

1. 커널 부팅 주소
ZTEXTADDR
압축 해제 코드가 실행되는 시작 주소입니다.MMU가 꺼져 있기 때문에 물리적 주소와 가상 주소의 구분이 없습니다.이 주소는 반드시 램의 주소가 아니라, 읽기, 쓰기, 주소 찾기를 지원하는 플래시 등 저장 중개가 될 수 있다.
Start address of decompressor. here's no point in talking about virtual or physical addresses here, since the MMU will be off at the time when you call the decompressor code. You normally call   the kernel at this address to start it booting. This doesn't have to be located in RAM, it can be in flash or other read-only or      read-write addressable medium.
arch/arm/boot/compressed/Makefile에서 분명히 말했어요.
#                             # We now have a PIC decompressor implementation.  Decompressors running# from RAM should not define ZTEXTADDR.  Decompressors running directly# from ROM or Flash must define ZTEXTADDR (preferably via the config)    # FIXME: Previous assignment to ztextaddr-y is lost here. See SHARKifeq ($(CONFIG_ZBOOT_ROM),y)  ZTEXTADDR   := $(CONFIG_ZBOOT_ROM_TEXT)ZBSSADDR    := $(CONFIG_ZBOOT_ROM_BSS)else                          ZTEXTADDR   := 0              ZBSSADDR    := ALIGN(8)       endif                        
      
ZRELADDR
RAM에서 커널이 시작되는 주소입니다.압축된 내장 이미지가 이 주소로 압축되어 실행됩니다.
This is the address where the decompressed kernel will be written, and eventually executed. The following constraint must be valid:
              __virt_to_phys(TEXTADDR) == ZRELADDR
       The initial part of the kernel is carefully coded to be position independent.
일반적으로 프로젝트 디렉토리에 정의됩니다. 예를 들면 다음과 같습니다.
arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x70008000arch/arm/mach-at91/Makefile.boot: zreladdr-y += 0x20008000arch/arm/mach-cns3xxx/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0xc0008000arch/arm/mach-davinci/Makefile.boot: zreladdr-y += 0x80008000arch/arm/mach-dove/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-ebsa110/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-exynos/Makefile.boot: zreladdr-y += 0x40008000arch/arm/mach-footbridge/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-gemini/Makefile.boot: zreladdr-y += 0x10008000arch/arm/mach-integrator/Makefile.boot: zreladdr-y += 0x00008000arch/arm/mach-iop13xx/Makefile.boot: zreladdr-y += 0x00008000
arch/arm/boot/Makefile에 지정된 값:
ZRELADDR := $(zreladdr-y)PARAMS_PHYS := $(params_phys-y)INITRD_PHYS := $(initrd_phys-y)
... ...
ifneq ($(LOADADDR),) UIMAGE_LOADADDR=$(LOADADDR)else ifeq ($(CONFIG_ZBOOT_ROM),y) UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) else UIMAGE_LOADADDR=$(ZRELADDR) endif endif
check_for_multiple_loadaddr =\
if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then\
echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)';\
echo 'This is incompatible with uImages';\
echo 'Specify LOADADDR on the commandline to build an uImage';\
false;\
fi
마지막 빨간색 설명에서 알 수 있듯이 코드에 zreladdr-y를 지정하지 않으면 컴파일된 명령줄에 LOADADDR를 지정하여 커널이 불러오는 실제 물리적 주소를 확인할 수 있다.
TEXTADDR
커널이 시작된 가상 주소는 ZRELADDR에 해당합니다.일반 커널에서 시작하는 가상 주소는 RAM의 첫 번째 뱅크 주소에 0x8000입니다.
       TEXTADDR = PAGE_OFFSET + TEXTOFFST
       Virtual start address of kernel, normally PAGE_OFFSET + 0x8000.This is where the kernel image ends up. With the latest kernels, it must be located at 32768 bytes into a 128MB region. Previous kernels placed a restriction of 256MB here.
TEXTOFFSET
커널 오프셋 주소입니다.arch/arm/makefile에서 설정합니다.
PHYS_OFFSET
RAM 첫 번째 뱅크의 물리적 시작 주소입니다.
Physical start address of the first bank of RAM.
PAGE_OFFSET
RAM 첫 번째 뱅크의 가상 시작 주소입니다.
       Virtual start address of the first bank of RAM. During the kernel
       boot phase, virtual address PAGE_OFFSET will be mapped to physical
       address PHYS_OFFSET, along with any other mappings you supply.
       This should be the same value as TASK_SIZE.
이 값은 make menuconfig에서 구성합니다.
1.2.내장 부팅 주소lds 결정.Bootp.lds : arch/arm/bootp
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0;
.text : {
   _stext = .;
   *(.start)
   *(.text)
   initrd_size = initrd_end - initrd_start;
   _etext = .;
}
}
에서. =0은(는) 압축 해제 코드가 실행되는 시작 주소가 0x0인 위치를 확인할 수 있습니다.ZTEXTADDR 값에 따라 선택할 가치가 결정됩니다.
Makefile : arch/arm/boot/compressed
ROM에서 커널을 시작하도록 설정하면 make menuconfig의 설정 인터페이스에서 압축 해제 코드의 시작 주소를 설정할 수 있습니다. 그렇지 않으면 압축 해제 코드의 시작 주소는 0x0입니다.실제로 기본적으로 ROM에서 시작할 때, 압축 해제 코드의 시작 주소도 0x0이다.
ifeq ($(CONFIG_ZBOOT_ROM),y)
ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR    := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR :=0                                                      
ZBSSADDR := ALIGN(4)
endif
SEDFLAGS    = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/                                                                                                                                             
……
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/mach-s3c2410/Makefile .config
       @sed "$(SEDFLAGS)"< $< > $@
@sed "$(SEDFLAGS)"<$<> $@규칙은 TEXTSTART는 ZTEXTADDR로 설정됩니다.TEXT_START는arch/arm/boot/compressed/vmlinux에 있습니다.lds.in에서 압축 해제 코드의 시작 주소를 설정하는 데 사용됩니다.
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = TEXT_START;  
_text = .;
.text : {
    _start = .;
    *(.start)
    *(.text)
*(.text.*)
……
}
}
내부 핵의 컴파일링은 vmlinux에 의존합니다.lds,vmlinux.lds는 vmlinux입니다.lds.생성아래 코드를 보면 커널이 시작된 가상 주소가 PAGE 로 설정되어 있음을 알 수 있습니다.OFFSET + TEXT_OFFSET, 커널이 시작되는 물리적 주소인 ZRELADDR는arch/arm/boot/Makefile에서 설정됩니다.
OUTPUT_ARCH(arm)
ENTRY(stext)
SECTIONS
{
#ifdef CONFIG_XIP_KERNEL
       . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
#else
       . = PAGE_OFFSET + TEXT_OFFSET;   
#endif
       .init : {                 /* Init code and data             */
              _stext = .;
                     _sinittext = .;
                     *(.init.text)
                     _einittext = .;
……
       }
}
# arch/arm/boot/Makefile
# Note: the following conditions must always be true:
#   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
#   PARAMS_PHYS must be within 4MB of ZRELADDR
#   INITRD_PHYS must be in RAM
ZRELADDR    := $(zreladdr-y)                                      
#---> zrealaddr-y is specified with 0x30008000 in arch/arm/boot/makefile.boot
PARAMS_PHYS := $(params_phys-y)
INITRD_PHYS := $(initrd_phys-y)
export ZRELADDR INITRD_PHYS PARAMS_PHYS
다음 명령을 통해 내장 이미지를 컴파일합니다. 인자 a,-e에서 입구 주소를 ZRELADDR로 설정합니다. 이 값은 위에 ZRELADDR: = $(zreladdr-y) 로 지정됩니다.
quiet_cmd_uimage= UIMAGE $@                                                                     
      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel\
                 -C none -a $(ZRELADDR) -e $(ZRELADDR)\
                 -n 'Linux-$(KERNELRELEASE)' -d $< $@
1.3.소결은 위에서 분석한 바와 같이 linux 커널이bootloader에 의해 RAM으로 복사된 후, 압축 해제 코드는ZTEXTADDR에서 실행되기 시작한다. (이 코드는 위치와 무관한 PIC (Position independent code).커널은 ZREALADDR, 즉 커널이 시작된 물리적 주소로 압축됩니다.이에 따라 커널이 시작되는 가상 주소는 다음과 같은 조건을 만족하는 TEXTADDR로 설정됩니다.
TEXTADDR = PAGE_OFFSET + TEXT_OFFSET
커널이 시작되는 물리적 주소 및 가상 주소는 다음 조건을 충족합니다.
ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)= virt_to_phys(TEXTADDR)
개발 보드가 smdk2410이라고 가정하면 다음과 같습니다.
커널이 시작된 가상 주소
TEXTADDR     = 0xC0008000
커널이 시작된 물리적 주소
ZRELADDR     = 0x30008000
플래시에서 직접 시작하려면 ZTEXTADDR 주소를 설정해야 합니다.
2. 내부 핵 가동 과정 분석 내부 핵 가동 과정은 크게 두 단계로 나눌 수 있는데 그것이 바로 내부 핵 이미지의 자체 유도이다.linux 내장 모듈의 초기화입니다.
startDecompress_kernel()Call_kernelStext:Prepare_namespaceDo_basic_setupinitRest_initSetup_arch ……Start_kernel_enable_mmuExecve(“/sbin/init”))

좋은 웹페이지 즐겨찾기