리눅스/커널2014. 3. 31. 10:14

early_param("HI_MEM", HI_MEM_Init) 

  --> __setup_param(str, fn, fn, 1) 으로 정의되어 있는데 이를 자세히 보면,

static const char __setup_str_##unique_id[] __initcost \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
  __used __section(.init.setup)
  __attribute__((aligned((sizeof(long))))) \
  = { __setup_str_##unique_id, fn, early }


long 사이즈로 align된 .init.setp섹션에 obs_kernel_param 구조체 형태의 __setup_##unique_id 안에 { __setup_str_##unique_id, fn, early } 형태로 초기화 시킨다. 


obs_kernel_param 구조체는 

const char *str
int (*setup_func)(char *);
int early;

로 구성되어 있다.

이렇게 설정된 early_param의 내용은 init/main.c에서 parse_early_options() --> parse_args("early options", cmdline, NULL, 0, do_early_param) --> parse_one()안에서
return handle_unknown에서 do_early_param이 실행된다.

do_early_param을 실행시킬 때, 그동안 쌓인 obs_kernel_param 리스트(?)들을 순회하면서 실행 시킨다.(섹션에 구조체가 리스트로 들어가기 보다는 각각의 구조체가 엔트리로 들어가는 거 같은데 좀 더 확인이 필요하다.)


__setup_start[] 와 __setup_end[]는 include/asm-generic/vmlinux.lds.h 에서 다음과 같이 정의되어 있다.


#define INIT_SETUP(initsetup_align) \ . = ALIGN(initsetup_align); \ VMLINUX_SYMBOL(__setup_start) = .; \ *(.init.setup) \ VMLINUX_SYMBOL(__setup_end) = .;

또한 INIT_SETUP은 arch/arm/kernel/vmlinux.lds.S에서 16byte(?)으로 align되어 있다.

.init.data : { #ifndef CONFIG_XIP_KERNEL INIT_DATA #endif INIT_SETUP(16) INIT_CALLS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS }


좀 더 자세히 봐야 하는데, 결국 맨 위, "HI_MEM"이라는 parameter에 대한 처리를 HI_MEM_init에서 처리할 수 있게 된다.


'리눅스 > 커널' 카테고리의 다른 글

Machine 이름 바꾸기  (0) 2014.04.03
Machine 이름 알아내기  (0) 2014.04.03
/dev/tty 와 /dev/console의 차이점  (0) 2014.02.05
FrameBuffer size 구하기  (0) 2013.12.11
[커널] FB 문서  (0) 2013.12.09
Posted by code cat