개발/arm64 linux 6 분석
early_param (setup_arch)
clucle
2025. 5. 31. 19:06
void __init __no_sanitize_address setup_arch(char **cmdline_p)
{
parse_early_param();
early param 이란 어떤것이고, 어떻게 사용하는지 알아보자.
early param
.init.setup 섹션에 미리 등록한 parameter 가 early param 으로 사용 가능합니다.
__setup_start 에 들어갈 수 있도록 매크로로 정의합니다.
extern const struct obs_kernel_param __setup_start[], __setup_end[];
/*
* Only for really core code. See moduleparam.h for the normal way.
*
* Force the alignment so the compiler doesn't space elements of the
* obs_kernel_param "array" too far apart in .init.setup.
*/
#define __setup_param(str, unique_id, fn, early) \
static const char __setup_str_##unique_id[] __initconst \
__aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(".init.setup") \
__aligned(__alignof__(struct obs_kernel_param)) \
= { __setup_str_##unique_id, fn, early }
/*
* NOTE: __setup functions return values:
* @fn returns 1 (or non-zero) if the option argument is "handled"
* and returns 0 if the option argument is "not handled".
*/
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)
// cmd line 을 복사후 파싱
void __init parse_early_param(void)
{
strscpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
parse_early_options(tmp_cmdline);
}
void __init parse_early_options(char *cmdline)
{
parse_args("early options", cmdline, NULL, 0, 0, 0, NULL, do_early_param);
}
static int __init do_early_param(char *param, char *val,
const char *unused, void *arg)
{
const struct obs_kernel_param *p;
for (p = __setup_start; p < __setup_end; p++) {
if (p->early && parameq(param, p->str)) {
if (p->setup_func(val) != 0)
pr_warn("Malformed early option '%s'\n", param);
}
}
/* We accept everything at this stage. */
return 0;
}
커널의 parameter
커널파라미터를 내부적으로 관리하기 위한 구조체
struct kernel_param {
const char *name;
struct module *mod;
const struct kernel_param_ops *ops;
const u16 perm;
s8 level;
u8 flags;
union {
void *arg;
const struct kparam_string *str;
const struct kparam_array *arr;
};
};
parse_one 의 동작
for (i = 0; i < num_params; i++) {
if (parameq(param, params[i].name)) {
// 인자로 들어온 param 이 있다면 set 후 return
// 찾지 못한경우 handle_unknown 호출
if (handle_unknown) { handle_unknown(); }