2025. 3. 6. 19:43ㆍ프로그래밍/시스템
4.2 기존 드라이버 포팅
기존 보드에서 사용되는 디바이스 드라이버를 확인하고, 이를 새로운 환경에 맞게 포팅하는 과정을 다룹니다.
리눅스에서는 lsmod, modinfo 등을 사용하여 현재 로드된 드라이버를 확인할 수 있으며, 필요한 드라이버를 분석, 수정, 빌드하여 새로운 환경에서 적용할 수 있습니다.
🔹 기존 보드에서 사용되는 드라이버 확인 (lsmod, modinfo)
✅ 1️⃣ 현재 로드된 커널 모듈 확인 (lsmod)
lsmod
출력 예시:
Module Size Used by
bcm2835_rng 16384 0
i2c_bcm2835 16384 0
bcm2835_codec 36864 0
bcm2835_v4l2 45056 0
- Module: 드라이버(커널 모듈) 이름
- Size: 모듈 크기
- Used by: 이 모듈을 사용 중인 다른 모듈 또는 프로세스
✅ 2️⃣ 특정 드라이버의 상세 정보 확인 (modinfo)
modinfo bcm2835_rng
출력 예시:
filename: /lib/modules/5.10.17-v7l+/kernel/drivers/char/hw_random/bcm2835-rng.ko
description: "BCM2835 Random Number Generator driver"
license: GPL
author: "Broadcom"
alias: platform:bcm2835-rng
depends:
vermagic: 5.10.17-v7l+ SMP mod_unload modversions ARMv7
- filename: 해당 드라이버의 실제 파일 경로
- description: 드라이버 설명
- license: 라이선스 정보
- depends: 필요한 다른 모듈
✅ 3️⃣ 특정 드라이버가 어떤 디바이스와 연결되어 있는지 확인
ls /sys/class/net/ # 네트워크 장치 목록 확인
ls /sys/class/gpio/ # GPIO 장치 확인
ls /sys/class/i2c-adapter # I2C 장치 확인
이 정보를 바탕으로 새로운 보드에서도 동일한 기능을 지원할 수 있도록 드라이버를 수정해야 합니다.
🔹 필요한 드라이버 코드 분석 및 수정
드라이버 포팅 과정에서 기존 커널의 드라이버 소스를 분석하고, 새로운 하드웨어 환경에 맞게 수정해야 합니다.
✅ 1️⃣ 기존 드라이버 소스 위치 확인 리눅스 커널의 드라이버 소스는 drivers/ 디렉토리에 저장됩니다.
cd linux/drivers/
ls
주요 디렉토리:
- drivers/char/ → 문자 장치 드라이버 (예: bcm2835_rng)
- drivers/block/ → 블록 장치 드라이버 (예: mmc, sd)
- drivers/net/ → 네트워크 드라이버 (예: bcmgenet)
- drivers/gpio/ → GPIO 드라이버
- drivers/i2c/ → I2C 드라이버
✅ 2️⃣ 드라이버 코드 분석 (drivers/char/bcm2835_rng.c 예시)
static int bcm2835_rng_probe(struct platform_device *pdev)
{
struct bcm2835_rng_priv *priv;
struct device *dev = &pdev->dev;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
return 0;
}
- probe() → 드라이버가 특정 하드웨어와 연결될 때 실행
- devm_kzalloc() → 커널 공간에 메모리 할당
- devm_platform_ioremap_resource() → 디바이스의 I/O 리소스를 매핑
✅ 3️⃣ 새로운 SoC에 맞게 드라이버 수정 만약 메모리 매핑 주소가 변경된 경우, 기존 드라이버에서 ioremap()을 호출하는 부분을 수정해야 합니다.
기존 코드:
priv->base = ioremap(0x3f100000, 0x1000);
새로운 SoC에서 사용하는 메모리 주소로 변경:
priv->base = ioremap(0x20000000, 0x1000);
✅ 4️⃣ 새로운 하드웨어의 디바이스 트리(DTS) 수정 드라이버가 새로운 SoC에서 동작하려면 디바이스 트리에 해당 장치가 정의되어 있어야 합니다.
기존 bcm2835_rng 드라이버가 지원하는 DTS 항목:
bcm2835_rng: rng@3f104000 {
compatible = "brcm,bcm2835-rng";
reg = <0x3f104000 0x1000>;
};
새로운 SoC에 맞게 수정:
my_rng: rng@20040000 {
compatible = "mycompany,my_rng";
reg = <0x20040000 0x1000>;
};
이제 드라이버가 새로운 SoC의 하드웨어와 연결될 수 있습니다.
🔹 드라이버 빌드 후 테스트 (insmod, rmmod)
✅ 1️⃣ 드라이버 빌드 수정한 드라이버를 빌드하려면 Makefile에 해당 드라이버를 추가하고 커널을 빌드해야 합니다.
예제 Makefile (drivers/char/Makefile 수정)
obj-$(CONFIG_BCM2835_RNG) += bcm2835_rng.o
빌드 명령어:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules -j$(nproc)
✅ 2️⃣ 빌드된 커널 모듈 확인
find . -name "bcm2835_rng.ko"
✅ 3️⃣ 드라이버 로드 (insmod)
sudo insmod bcm2835_rng.ko
- insmod → 커널 모듈을 로드
- /dev/ 디렉토리에 해당 장치 파일이 생성되는지 확인
✅ 4️⃣ 드라이버 언로드 (rmmod)
sudo rmmod bcm2835_rng
- rmmod → 커널 모듈을 제거
✅ 5️⃣ 모듈 로그 확인 (dmesg)
dmesg | tail -20
출력 예시:
[ 123.456789] bcm2835_rng: Registered new RNG driver
✅ 6️⃣ 자동 로딩 설정 (modprobe) 부팅 시 자동으로 드라이버를 로드하려면 modules.conf에 추가:
echo "bcm2835_rng" | sudo tee -a /etc/modules
✅ 정리
- 기존 보드에서 사용되는 드라이버 확인
- lsmod → 현재 로드된 드라이버 확인
- modinfo → 특정 드라이버 정보 확인
- /sys/class/ → 디바이스와 연결된 드라이버 확인
- 드라이버 코드 분석 및 수정
- drivers/ 디렉토리에서 기존 소스 분석 (probe(), ioremap() 등)
- 새로운 SoC의 메모리 주소 및 레지스터 값 수정
- 디바이스 트리(DTS)를 업데이트하여 새로운 보드에서 장치 인식 가능하게 설정
- 드라이버 빌드 및 테스트
- make modules → 드라이버 빌드
- insmod, rmmod → 드라이버 로드 및 언로드
- dmesg → 로그 확인
- modprobe 설정을 통해 부팅 시 자동 로딩 가능
'프로그래밍 > 시스템' 카테고리의 다른 글
커널 포팅 (5. 고급 커널 포팅 및 최적화 / 5.1 부트로더 커스터마이징) (0) | 2025.03.06 |
---|---|
커널 포팅 (4. 드라이버 포팅 / 4.3 새로운 드라이버 추가하기) (0) | 2025.03.06 |
커널 포팅 (4. 드라이버 포팅 / 4.1 기본적인 디바이스 드라이버 개념) (0) | 2025.03.06 |
커널 포팅 (3. 커널 포팅 기본 실습 / 3.3 부트 로그 분석 및 디버깅) (0) | 2025.03.06 |
커널 포팅 (3. 커널 포팅 기본 실습 / 3.2 새로운 SoC 지원을 위한 포팅) (0) | 2025.03.06 |