본문 바로가기
인프런/한국 제일 쉬운 리눅스 커널

커널 컴파일

by book_lover 2025. 1. 7.
apt-get update
apt-get upgrade
apt-get install git bc bison flex libssl-dev vim
cd /
mkdir project
cd project
mkdir linuxSrc
cd linuxSrc
  • bashrc 파일 : 사용자의 Bash 쉘 개인 초기화 스크립트

make

특정 config 파일을 사용하여 빌드 할 수 있음

  • arch/ 폴더안에 SoC별로 config 파일을 모아저 있음.
#!/bin/bash

# AMD64 및 ARM64 커널 컴파일 스크립트
# 작성 날짜: 2025년 1월 7일

# 사용자가 선택할 수 있는 옵션 출력
echo "=== 리눅스 커널 컴파일 ==="
echo "1. AMD64 (x86_64)"
echo "2. ARM64 (aarch64)"
read -p "컴파일할 아키텍처를 선택하세요 (1 또는 2): " ARCH_CHOICE

# 공통 변수 설정
KERNEL_VERSION="6.0.7"
KERNEL_SOURCE="linux-$KERNEL_VERSION.tar.xz"
KERNEL_DIR="linux-$KERNEL_VERSION"

# 의존성 설치
echo "=== 의존성 설치 중 ==="
sudo apt update
sudo apt install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev gcc-aarch64-linux-gnu

# 커널 소스 다운로드 및 압축 해제
if [ ! -f "$KERNEL_SOURCE" ]; then
    echo "=== 커널 소스 다운로드 중 ==="
    wget "https://cdn.kernel.org/pub/linux/kernel/v6.x/$KERNEL_SOURCE"
fi

if [ ! -d "$KERNEL_DIR" ]; then
    echo "=== 커널 소스 압축 해제 중 ==="
    tar xvf "$KERNEL_SOURCE"
fi

cd "$KERNEL_DIR"

# 아키텍처별 설정
if [ "$ARCH_CHOICE" -eq 1 ]; then
    # AMD64 설정
    echo "=== AMD64 커널 설정 ==="
    cp /boot/config-$(uname -r) .config
    make menuconfig
    echo "=== AMD64 커널 빌드 중 ==="
    make -j$(nproc)
    sudo make modules_install
    sudo make install
    sudo update-grub
    echo "=== AMD64 커널 빌드 완료! 시스템을 재부팅하세요. ==="

elif [ "$ARCH_CHOICE" -eq 2 ]; then
    # ARM64 설정
    echo "=== ARM64 커널 설정 ==="
    make ARCH=arm64 defconfig
    make ARCH=arm64 menuconfig
    echo "=== ARM64 커널 빌드 중 ==="
    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
    mkdir -p output-arm64
    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install INSTALL_MOD_PATH=output-arm64
    echo "=== ARM64 커널 빌드 완료! 결과물은 arch/arm64/boot/ 디렉토리에 있습니다. ==="

else
    echo "잘못된 선택입니다. 스크립트를 다시 실행하세요."
fi

exit 0

스크립트 기능 설명

  • 의존성 설치: build-essential, libncurses-dev 등 필수 패키지를 설치합니다.
  • 커널 소스 다운로드: 최신 리눅스 커널 소스를 자동으로 다운로드합니다.
  • 아키텍처별 설정:
    • AMD64는 현재 시스템의 .config 파일을 복사하여 기본 설정으로 사용합니다.
    • ARM64는 defconfig를 기반으로 기본 설정을 로드하며, 크로스 컴파일러(aarch64-linux-gnu-gcc)를 사용합니다.
  • 빌드 결과물:
    • AMD64: /boot 디렉토리에 설치되며, 부트로더가 업데이트됩니다.
    • ARM64: arch/arm64/boot/ 디렉토리에 생성됩니다(Image, dtb 등).

결과

이 스크립트를 사용하면 AMD64 및 ARM64 아키텍처용 리눅스 커널을 간단히 컴파일하고, 필요에 따라 설치하거나 결과물을 확인할 수 있습니다!

 

라즈베리 커널 빌드는 아래 사이트에서 확인 가능

https://www.raspberrypi.com/documentation/computers/linux_kernel.html#download-kernel-source

 

The Linux kernel - Raspberry Pi Documentation

The official documentation for Raspberry Pi computers and microcontrollers

www.raspberrypi.com

라즈베리파이 5 기준으로 변경

#!/bin/bash

echo "configure build output path"

KERNEL_TOP_PATH="$( cd "$(dirname "$0")" ; pwd -P)"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "$OUTPUT"

KERNEL=kernel_2712
BUILD_LOG="$KERNEL_TOP_PATH/rpi_build_log.txt"

echo "move kernel source"
cd linux

echo "make defconfig"
make O=$OUTPUT bcm2712_defconfig

echo "kernel build"
make O=$OUTPUT Image.gz modules dtbs -j6 2>&1 | tee $BUILD_LOG


######크로스 컴파일
#!/bin/bash

# CentOS 9에서 ARM64 커널 빌드 스크립트
# 작성 날짜: 2025년 1월 8일

echo "=== CentOS 9 환경에서 ARM64 커널 빌드 시작 ==="

# 필요한 패키지 설치
echo "=== 필요한 패키지 설치 ==="
sudo dnf install -y bc bison flex elfutils-libelf-devel openssl-devel ncurses-devel make gcc wget tar

# ARM64 크로스 컴파일러 확인 및 설치
if ! command -v aarch64-linux-gnu-gcc &>/dev/null; then
    echo "ARM64 크로스 컴파일러가 없습니다. 설치를 진행합니다."
    wget https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
    tar -xf arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
    sudo mv arm-gnu-toolchain-* /opt/arm-toolchain
    echo 'export PATH=/opt/arm-toolchain/bin:$PATH' >> ~/.bashrc
    source ~/.bashrc
fi

# 빌드 출력 경로 설정
echo "=== 빌드 출력 경로 설정 ==="
KERNEL_TOP_PATH="$( cd "$(dirname "$0")" ; pwd -P)"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "빌드 출력 경로: $OUTPUT"

# 커널 이름 및 로그 파일 설정
KERNEL=kernel_2712
BUILD_LOG="$KERNEL_TOP_PATH/rpi_build_log.txt"

# 커널 소스 디렉토리로 이동
echo "=== 커널 소스 디렉토리로 이동 ==="
cd linux || { echo "linux 디렉토리가 존재하지 않습니다."; exit 1; }

# 기본 설정 생성 (bcm2712_defconfig)
echo "=== bcm2712_defconfig 실행 ==="
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=$OUTPUT bcm2712_defconfig

# 커널 빌드 시작
echo "=== 커널 빌드 시작 ==="
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=$OUTPUT Image.gz modules dtbs -j$(nproc) 2>&1 | tee $BUILD_LOG

echo "=== ARM64 커널 빌드 완료 ==="
#!/bin/bash

echo "configure build output path""

KERNEL_TOP_PATH="$( cd "$(dirname "$0")" ; pwd -P)"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "$OUTPUT"

KERNEL=kernel_2712

cd out

make O=$OUTPUT -j6 modules_install
sudo cp /boot/firmware/$KERNEL.img /boot/firmware/$KERNEL-backup.img
sudo cp $OUTPUT/arch/arm64/boot/Image.gz /boot/firmware/$KERNEL.img
sudo cp $OUTPUT/arch/arm64/boot/dts/broadcom/*.dtb /boot/firmware/
sudo cp $OUTPUT/arch/arm64/boot/dts/overlays/*.dtb* /boot/firmware/overlays/
sudo cp $OUTPUT/arch/arm64/boot/dts/overlays/README /boot/firmware/overlays/



####크로스 인스톨
#!/bin/bash

# CentOS 9에서 ARM64 커널 모듈 설치 스크립트
# 작성 날짜: 2025년 1월 8일

echo "=== ARM64 커널 모듈 설치 시작 ==="

# 빌드 출력 경로 설정
KERNEL_TOP_PATH="$( cd "$(dirname "$0")" ; pwd -P)"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "빌드 출력 경로: $OUTPUT"

# 커널 소스 디렉토리로 이동
cd linux || { echo "linux 디렉토리가 존재하지 않습니다."; exit 1; }

# 모듈 설치
echo "=== 모듈 설치 중 ==="
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- O=$OUTPUT -j$(nproc) modules_install

echo "=== ARM64 커널 모듈 설치 완료 ==="

커널복사 스크립트

# 기존 커널 백업 및 새 커널 복사
echo "=== 기존 커널 백업 및 새 커널 복사 ==="
sudo cp /boot/firmware/$KERNEL.img /boot/firmware/$KERNEL-backup.img || echo "기존 커널 백업 실패 (백업 파일이 없을 수 있음)"
sudo cp $OUTPUT/arch/arm64/boot/Image.gz /boot/firmware/$KERNEL.img
sudo cp $OUTPUT/arch/arm64/boot/dts/broadcom/*.dtb /boot/firmware/
sudo cp $OUTPUT/arch/arm64/boot/dts/overlays/*.dtb* /boot/firmware/overlays/
sudo cp $OUTPUT/arch/arm64/boot/dts/overlays/README /boot/firmware/overlays/

echo "=== ARM64 커널 빌드 및 설치 완료 ==="

전처리 코드 생성

코드 분석하기 위해

Makefile의 KBUILD_CFLAGS에 추가

  • save-temps=obj 

*.i파일 - include한 파일을 포함한 파일

*.s 파일 - 어셈블리코드

 

build_preprocess.sh

#!/bin/bash

echo "configure build output path"

KERNEL_TOP_PATH="$( cd "$(dirname "$0")" ; pwd -P)"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "$OUTPUT"

KERNEL=kernel_2712
BUILD_LOG="$KERNEL_TOP_PATH/rpi_preprocess_build_log.txt"

PREPROCESS_FILE=$1

echo "build preprocess file: $PREPROCESS_FILE"

echo "move kernel source"
cd linux

echo "make defconfig"
make O=$OUTPUT bcm2712_defconfig

echo "kernel build"
make $PREPROCESS_FILE O=$OUTPUT -j4 2>&1 | tee $BUILD_LOG
./build_preprocess.sh [파일명]

# 예
./build_preprocess.sh /kernel/sched/core.i

objdump

바이너리 유틸리티

  • objdump: 라이브러리, ELF 파일(바이트코드 컨셉(?), 리눅스라는 운영체제가 해석할 수 있는 어떠한 파일)을 어셈블리어로 출력
  • as : 어셈블러
  • Id: 링커
  • addr2line: 주소를 파일과 라인으로 출력
  • nm : 오브젝트 파일의 심벌을 출력
  • readlf: ELF 파일의 내용을 출력