본문 바로가기

Core BSP 분석

(119)
[리눅스커널] GCC: notrace 옵션 - no_instrument_function walk_stackframe() 함수의 구현부를 보면 notrace 키워드로 선언됐음을 알 수 있습니다. https://elixir.bootlin.com/linux/v4.19.30/source/arch/arm/kernel/stacktrace.c void notrace walk_stackframe(struct stackframe *frame, int (*fn)(struct stackframe *, void *), void *data) { while (1) { int ret; if (fn(frame, data)) break; ret = unwind_frame(frame); if (ret < 0) break; } } EXPORT_SYMBOL(walk_stackframe); 이 함수를 전처리 코드에서 확인하면 ..
[리눅스커널] ssize_t와 size_t의 실체 ssize_t와 size_t 타입의 실체를 확인해보자. 아래 코드를 전처리 코드로 확인해볼까? static ssize_t default_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) { return 0; } size_t 타입의 정체 먼저 size_t의 정체를 확인해보자. 280 # 55 "/root/src/kernel_src/linux/include/linux/types.h" 281 typedef __kernel_size_t size_t; size_t 는 __kernel_size_t로 캐스팅 된다. 201 # 68 "/root/src/kernel_src/linux/include/uapi/asm-generic/posix..
[Crash-Utility][리눅스커널][디버깅] Radix Tree(라덱스-트리) 디버깅 하기(크래시 유틸리티) 리눅스 커널에서는 라덱스 트리로 핵심 자료구조를 관리합니다. 이번 시간에는 크래시 유틸리티로 라덱스 트리를 디버깅하는 방법을 소개합니다. 라덱스 트리를 보기 위한 명령어 크래시 유틸리티로 라덱스 트리 노드를 보기 위한 명령어 포멧은 다음과 같습니다. tree -t radix -N (struct radix_tree_node *) 구조체 주소 struct radix_tree_node 구조체 시작 주소만 알면 됩니다. struct radix_tree_node 구조체 주소가 0xFFFFFFFF3A806E79 인 경우 출력 결과는 다음과 같습니다. crash64_kaslr> tree -t radix -N 0xFFFFFFFF3A806E79 ffffffff3f53c180 ffffffff3f53c4c0 ffffffff..
[리눅스커널] 비트 마스크를 어셈블리 코드로 빨리 읽는 방법 - HARDIRQ_MASK, SOFTIRQ_MASK, NMI_MASK 이번에는 비트 마스크를 C 코드가 아닌 어셈블리 코드로 읽는 방법을 소개합니다. in_interrupt() 함수 소개 in_interrupt() 함수는 현재 프로세스가 인터럽트 컨택스트인지 알려주는 기능입니다. [https://elixir.bootlin.com/linux/v4.19.30/source/include/linux/preempt.h] #define in_interrupt() (irq_count()) in_interrupt() 함수 코드를 보면 irq_count() 함수로 치환됩니다. [https://elixir.bootlin.com/linux/v4.19.30/source/include/linux/preempt.h] #define irq_count() (preempt_count() & (HARDI..
[리눅스커널] smp thread에 대해서 smpboot(smp thread) 스레드 사용 배경 최근에 사용되는 대부분 시스템은 멀티 프로세서 기반으로 실행됩니다. 예를 들어 인터넷이나 TV 광고에서 "최신 인텔 멀티 프로세서 코어가 적용된 제품"이란 이야기가 들리죠. 일반 대중이 하나 이상 쓰고 있는 휴대폰도 멀티 프로세서 시스템 기반입니다. 휴대폰에는 Arm 프로세서가 탑재됐는데, CPU 코어의 갯수가 8개 이상 구성돼 있죠. 리눅스 커널에서도 이런 멀티 프로세서 구조에서 이를 소프트웨어로 처리하는 드라이버와 같은 존재가 있는데요. 이를 smpboot 혹은 smp 핫 플러그 스레드라고 합니다. smpboot(smp thread) 스레드 확인하기 그렇다면 smpboot로 등록한 커널 프로세스는 어떻게 확인할 수 있을까요? 리눅스 터미널에서 'p..
[리눅스커널][디버깅] 슬럽(슬랩) 캐시 오브젝트 T32로 메모리 디버깅하기 리눅스 커널 동적 메모리 할당을 위해 슬럽 캐시를 씁니다. 이번 시간에서는 kmalloc-64 슬럽 캐시 자료 구조를 통해 kmalloc-64 슬럽 오브젝트를 확인하는 방법을 소개합니다. 슬럽 캐시 확인하기 먼저 kmalloc-size 타입 슬럽 캐시를 관리하는 kmalloc_caches 전역 변수를 보겠습니다. kmalloc_caches 전역 변수의 세부 필드는 다음과 같습니다. (static struct kmem_cache * [14]) kmalloc_caches = ( [0] = 0x0, [1] = 0x0, [2] = 0xF1401E00, // "kmalloc-192" [3] = 0x0, [4] = 0x0, [5] = 0x0, [6] = 0xF1401F00 -> ( (struct kmem_cache..
[리눅스커널][디버깅] 유저공간 High Memory Zone 페이지 할당 과정 커널 크래시가 발생한 콜스택은 다음과 같습니다. 프로세스는 이름은 Debugger인데 유저 프로세스입니다. -001|__dabt_svc(asm) -->|exception -002|__list_del(inline) -002|list_del(inline) -002|buffered_rmqueue(inline) -002|get_page_from_freelist(?, ?, order = 0, ?, high_zoneidx = 0, alloc_flags = 449, pref -003|__alloc_pages_nodemask(gfp_mask = 33685722, order = 0, zonelist = 0xC1731380, nodema -004|__alloc_zeroed_user_highpage(inline) -004|..
[Linux][Kernel] preempt_disable()/preempt_enable() 주의 사항 preempt_disable() 함수를 쓸 때 주의해야 할 점이 있습니다. preempt_disable() 함수는 preempt_enable() 함수와 반드시 Pair로 써야 합니다. preempt_disable() 함수를 호출한 다음 스케줄링 동작을 수행하는 함수를 쓰면 리눅스 시스템은 오동작합니다. 예를 들어 다음과 같은 드라이버를 초기화하는 코드를 예를 들겠습니다. 1 void configure_something_driver(void) 2 { 3 preempt_disable(); 4 5 do_something(); 6 mdelay(100); 7 do_something(); 8 9 preempt_enable(); 10 } 5~7 번 코드가 실행할 때 Preemption이 되면 안된다고 판단했습니다. ..