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 |