Linux 커널 코드에서 "EXPORT_SYMBOL"의 의미는 무엇입니까?
48 struct snd_card *snd_cards[SNDRV_CARDS];
49 EXPORT_SYMBOL(snd_cards);
나는 그것의 의미와 그것이 왜 사용되는지 이해할 수 없다.나는 그것에 대해 알아보려고 했지만 그것의 의미를 이해하지 못했다.
동적으로 로드된 모듈에 접근할 수 단, 모듈이 "Dynamic하게 로드된 모듈"을 합니다).extern
선언)을 클릭합니다.
얼마 전에 어떤 분이 사용법을 물어보셨어요.
여기 좋은 설명이 있다.
https://www.quora.com/What-is-the-difference-between-extern-and-EXPORT_SYMBOL-in-Linux-kernel-codes
Extern은 C 스토리지 클래스의 키워드입니다.커널에서는 다른 C 코드와 마찬가지로 컴파일러에게 자신이 수식하는 변수나 함수의 정의가 다른 "파일" 또는 보다 정확하게 번역 유닛(프로그래밍)인 위키피디아에 구현되어 있음을 알립니다.이를 정의하는 변환 유닛은 정적 수식자를 사용하지 마십시오.따라서 기호 테이블에는 대응하는 엔트리가 있습니다.링크 시 심볼은 정상적으로 해결됩니다."extern"에 대한 커널 고유의 내용은 없습니다.
EXPORT_SYMBOL()은 Linux 커널 헤더가 정의하는 매크로입니다.그것은 외부와 많은 공통점을 가지고 있지 않다.Kbuild 메커니즘에 참조되는 기호가 커널 기호의 글로벌목록의 일부가 되어야 함을 알립니다.그러면 커널 모듈이 액세스할 수 있습니다.물론 (모듈이 아닌) 커널 자체에 내장된 코드는 일반 C에 따라 외부 선언을 통해 모든 비정적 심볼에 액세스할 수 있습니다.EXPORT_SYMBOL() 메커니즘을 사용하면 로드 가능한 모듈에서 사용하는 기호도 내보낼 수 있습니다.흥미로운 점은 한 모듈이 내보낸 기호에 종속된 다른 모듈에 액세스할 수 있다는 것입니다!
요약하자면, extern은 커널 고유의 것이 아닙니다.다른 변환 유닛에서 비정적 기호에 대한 선언을 수식하기 위해 사용됩니다.EXPORT_SYMBOL()은 Linux 커널에 고유합니다.정의의 변환 단위에서 이 기호를 로드 가능한 모듈에서 사용할 수 있도록 하기 위해 사용됩니다.
따라서 EXPORT_SYMBOL은 외부와 같은 메커니즘일 뿐이지만 파일이 아닌 로딩 가능한 모듈 간의 참조용입니다.
앞으로 나아가기 위해서는 외부는 기초인 C형이기 때문에 외부로 인해 획득된 것으로 추측할 수 있습니다.
여기 단서가 있다.
https://elixir.bootlin.com/linux/v4.6.7/source/include/linux/export.h#L56
#define EXPORT_SYMBOL(sym) \
__EXPORT_SYMBOL(sym, "")
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] __attribute__((section("__ksymtab_strings"), aligned(1))) = VMLINUX_SYMBOL_STR(sym); \
extern const struct kernel_symbol __ksymtab_##sym; \
__visible const struct kernel_symbol __ksymtab_##sym __used __attribute__((section("___ksymtab" sec "+" #sym), unused)) = { (unsigned long)&sym, __kstrtab_##sym }
먼저 외부 증상을 선언합니다.
그런 다음 문자열 __kstrtab_##sym == VMLINUX_SYMBOL_STR(sym)을 입력합니다.
마지막으로 extern structure kernel_brack__ksymtab_#brack = { ( long )&brack, __kstrtab_#brack}. &brack은 함수나 변수 등의 심볼의 실제 주소를 기록합니다.
답변 자체가 아니라 제 코멘트에서 약속한 대로 내보낸 기호가 정적이 아니어도 된다는 것을 보여 줍니다.다음 2개의 모듈에서 이를 시연합니다.
/* mod1.c */
#include <linux/module.h>
static int mod1_exp_func(int i)
{
pr_info("%s:%d the value passed in is %d\n",
__func__, __LINE__, i);
return i;
}
EXPORT_SYMBOL(mod1_exp_func); /* export static symbol */
static int __init mod1_init(void)
{
pr_info("Initializing simple mod\n");
return 0;
}
static void __exit mod1_exit(void)
{
pr_info("This module is exiting\n");
}
module_init(mod1_init);
module_exit(mod1_exit);
MODULE_LICENSE("GPL v2");
그리고 두 번째 모듈은
/* mod2.c */
#include <linux/module.h>
extern int mod1_exp_func(int);
static int __init mod2_init(void)
{
pr_info("Initializing mod2\n");
pr_info("Calling exported function in mod1\n");
mod1_exp_func(3);
return 0;
}
static void __exit mod2_exit(void)
{
pr_info("mod2 exiting\n");
}
module_init(mod2_init);
module_exit(mod2_exit);
MODULE_LICENSE("GPL v2");
이것들은 Cent에서 테스트되었습니다.OS 6 & CentOS 7: 커널 2.6.32 및 3.10 (각각).mod1.ko를 로드한 후 mod2.ko를 로드하면 mod1_exp_func()에 전달된 값이 커널 로그 버퍼로 출력됩니다.
언급URL : https://stackoverflow.com/questions/9836467/whats-meaning-of-export-symbol-in-linux-kernel-code
'programing' 카테고리의 다른 글
AssertjUnit의 문자열에 포함됨 (0) | 2022.06.20 |
---|---|
다차원 어레이, Vuex 및 돌연변이 (0) | 2022.06.20 |
Vuex는 언제 사용해야 합니까? (0) | 2022.06.20 |
선택 옵션을 즉시 동적으로 생성 (0) | 2022.06.20 |
Java 11 패키지 javax.xml.bind가 없습니다. (0) | 2022.06.20 |