리눅스 커널 포팅 가이드

대문 / 프로그래밍 / 리눅스 커널 포팅 가이드

리눅스 커널 포팅 가이드

1.1. 개요

리눅스 커널은 "[https]리누스 베네딕트 토르발스 (Linus Benedict Torvalds)[](https://en.wikipedia.org/wiki/Linus_Torvalds)"가 개발하여 1991년에 처음으로 v0.01이 Copyleft로 처음 공개되어진 커널입니다. 현재는 전세계 수많은 개발자들이 협력하여 커널이 개발되고 있습니다.

버전이 올라가면서 수많은 발전을 하고 있는 부분에 대해서 어떤 변화를 가져왔고 어떻게 바뀌는지 정리를 시작해봅니다. 커널 개발하면서 겪었던 사항을 조금씩 정리해보겠습니다.

본 문서는 개인적인 해석관점에서 작성되었으므로 사실과 다른 부분이 있을지도 모릅니다. 만약 올바르지 않은 사항이 있다면 알려주세요.

1.2. Kernel 프로그래밍을 위해서 알아야 할 것들

1.2.1. Kernel build

1.2.2. Kernel vs User side 구분

Kernel code와 User side application을 source상에서 구분해야 할 경우(Kernel과 User side를 모두 하나의 소스에 구현하는 경우)가 있는데 이 경우 다음과 같이 구분할 수 있습니다.
#if defined(__KERNEL__)
  /* Kernel code 영역 */
#else
  /* User side application 영역 */
#endif

1.2.3. Kernel version에 따른 호환성 구현

LINUX_VERSION_CODE 상수는 현재 빌드한 커널의 버전 상수를 가지고 있습니다. 이 상수를 KERNEL_VERSION(<VERSION>,<PATCHLEVEL>,<SUBLEVEL>) macro 로 지정한 버젼과 비교하여 호환에 맞는 구현을 구분하도록 할 수 있습니다.
#include <linux/version.h>
#include <linux/kernel.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)
    /* Kernel version 4.15 이상에서 작동하는 코드 */
#else
    /* Kernel version 4.15 미만에서 작동하는 코드 */
#endif

1.2.4. Kernel config 식별

  • IS_ENABLED(<config-name>) macro
    #if IS_ENABLED(CONFIG_VLAN_8021Q)
        /* CONFIG_VLAN_8021Q 가 Kernel config에서 y 또는 m으로 설정되었음 */
    #endif
    

1.2.5. Kernel module 작성

1.2.6. 디버그(Debug) / 분석

1.3. Kernel version별 주요 변화

  • v6.15
    • x86계열의 경우 gcc v8.1.0이상의 버젼을 요구합니다.
    • kernel modules 빌드시 EXTRA_AFLAGS, EXTRA_CFLAGS, EXTRA_CPPFLAGS, EXTRA_LDFLAGS가 더 이상 지원되지 않습니다. (asflags-y, ccflags-y, cppflags-y, ldflags-y 로 사용해야 합니다.)
      • scripts/Makefile.lib 의 다음 부분이 제거되어 더 이상 호환되지 않습니다.
        - asflags-y  += $(EXTRA_AFLAGS)
        - ccflags-y  += $(EXTRA_CFLAGS)
        - cppflags-y += $(EXTRA_CPPFLAGS)
        - ldflags-y  += $(EXTRA_LDFLAGS)
        

1.4. Kernel source directory

1.4.1. scripts

  • scripts/min-tool-version.sh 에서 빌드에 필요한 binutils / gcc / llvm / rustc / bindgen 등의 최소 요구되는 버전을 체크합니다.

1.4.2. arch

1.4.3. block

1.4.4. certs

1.4.5. crypto

1.4.6. Documentation

1.4.7. drivers

1.4.8. fs

1.4.9. include

  • debug
    • pr_warning 함수는 v5.5부터 pr_warn으로 변경되었습니다. (pr_warn 또는 printk(KERN_WARNING pr_fmt("<...>", <...>) 으로 사용해야 합니다.)
  • 시간
    • time_t 자료형은 v5.6부터 deprecated 되었습니다. (v3.19부터 도입된 timekeeping/ktime으로 사용해야 합니다.)
    • struct timeval 자료형은 v4.15부터 deprecated 되었습니다. (ktime 계열을 사용해야 합니다.)
  • RCU(Read-Copy-Update)
    • call_rcu_bh는 v5.1부터 deprecated 되었습니다. (call_rcu로 사용해야 합니다.)
    • rcu_barrier_bh는 4.20부터 deprecated 되었습니다. (rcu_barrier로 사용해야 합니다.)

1.4.10. init

1.4.11. io_uring

1.4.12. ipc

1.4.13. kernel

  • 시간
    • CLOCK_MONOTONIC 계열 (절대 시간 함수, 정방향 흐름만 진행되는 시간계이며 임의로 변경할 수 없는 시간)
      • ktime_get_ts / get_monotonic_* 함수는 deprecated 되었습니다.
      • ktime_get / ktime_get_seconds / ktime_get_ns / ktime_get_ts64 함수로 사용할 수 있습니다.
    • CLOCK_REALTIME 계열 (시스템 시간 함수, epoch 시간으로 동기화등에 따른 변경이 가능한 시간)
      • do_gettimeofday / getnstimeofday / getnstimeofday64 / ktime_get_real_ts 함수는 deprecated 되었습니다.
      • ktime_get_real / ktime_get_real_seconds / ktime_get_real_ns / ktime_get_real_ts64 함수로 사용할 수 있습니다.
    • CLOCK_BOOTTIME 계열 (부팅 후 경과 시간, 정방향 흐름만 진행되는 시간계이며 부팅 직후 경과된 시간)
      • current_kernel_time / current_kernel_time64 함수는 deprecated 되었습니다.
      • ktime_get_boottime / ktime_get_boottime_seconds / ktime_get_boottime_ns / ktime_get_boottime_ts64 함수로 사용할 수 있습니다.
    • tick 계열
      • jiffies / jiffies64 변수화 매크로를 사용할 수 있습니다.

1.4.14. lib

1.4.15. LICENSES

1.4.16. mm

1.4.17. net

  • bridge
    • br_port_exists함수는 v5.2부터 deprecated 되었습니다. (netif_is_bridge_port로 사용해야 합니다.)
1.4.17.1. struct net_device
  • net_device ifname
    printk(KERN_INFO "this dev's ifname is %s\n", netdev_name(dev));
    
  • ifalias
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0) /* rcu ifalias */
            const struct dev_ifalias *alias = rcu_dereference(dev->ifalias);
            if(alias) {
                    printk(KERN_INFO "ifalias=%s\n", alias->ifalias);
            }
    #else
            if(dev->ifalias) {
                    printk(KERN_INFO "ifalias=%s\n", dev->ifalias);
            }
    #endif
    
  • netif_has_l3_rx_handler / IFF_L3MDEV_RX_HANDLER
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,20,7) /* netif_has_l3_rx_handler */
            if(netif_has_l3_rx_handler(dev)) { /* IFF_L3MDEV_RX_HANDLER */
                    printk(KERN_INFO "this dev is l3mdev_rx\n");
            }
    #endif
    
  • netif_is_failover / IFF_FAILOVER, netif_is_failover_slave / IFF_FAILOVER_SLAVE
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,0) /* netif_is_failover/netif_is_failover_slave IFF_FAILOVER/IFF_FAILOVER_SLAVE */
            if(netif_is_failover(dev)) { /* IFF_FAILOVER */
                    printk(KERN_INFO "this dev is failover\n");
            }
            if(netif_is_failover_slave(dev)) { /* IFF_FAILOVER_SLAVE */
                    printk(KERN_INFO "this dev is failover_port\n");
            }
    #endif
    
  • is_vlan_dev / IFF_802_1Q_VLAN
    #if IS_ENABLED(CONFIG_VLAN_8021Q)
            if(is_vlan_dev(dev)) { /* IFF_802_1Q_VLAN */
                    printk(KERN_INFO "this dev is vlan\n");
            }
    #endif
    
  • is LLTX / NETIF_F_LLTX
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,12,0) /* LLTX flag */
            if(!!dev->lltx) {
                    printk(KERN_INFO "this dev is lltx\n");
            }
    #else
            if(!!(dev->features & NETIF_F_LLTX)) {
                    printk(KERN_INFO "this dev is lltx\n");
            }
    #endif
    

1.4.18. rust

1.4.19. samples

1.4.20. security

1.4.21. sound

1.4.22. tools

1.4.23. usr

1.4.24. virt

1.5. 참고자료

Retrieved from https://www.minzkn.com:443/moniwiki/wiki.php/LinuxKernelPortingGuide
last modified 2025-10-24 18:39:14