새해 복 많이 받으십시요.
보드 : MDS rebis s3c2440a
커널 : 2.6.13
2.4 용으로 작성했던 cam driver 를 2.6.13에 붙이고 있습니다.
드라이버를 2.6 스타일로 변경하고 컴파일까지 잘 마무리 되었습니다. 이제 올리면 잘 돌아가겠지 하는 생각으로 insmod cam_driver.ko 를 했는데 전혀 예상치 못한 에러가 발생했습니다.
poplinux@rebis modules]$ insmod cam_driver.ko
Using cam_driver.ko
Unable to handle kernel paging request at virtual address f08000000
pgd = c7b44000
[f08000000] *pgd=00000000
Internal erro: Oops: 5 [#1]
Modules linked in: cam_driver videodev
CPU: 0
PC is at camif_setup_sensor+0x48/0xcc [cam_driver]
LR is at schedule_timeout+0x98/0xbc
.
.
.
.
디바이스 드라이버를 올리면 다음과 같은 순서로 함수가 호출됩니다. (물론 임의로 짠 거여서 중요한 내용은 아닙니다.)
camif_m_in()
camif_init()
camif_setup_sensor()
문제는 camif_setup_sensor() 함수를 실행할 때 레지스터 셋팅을 하는 부분에서 발생됩니다.
camif_setup_sensor(){
rCIRSRCFMT |= (0x1<<31); // by lovejin
}
위와 같이 레지스터 셋팅을 하면 커널 패닉이 발생되는 것입니다.
rCIRSRCFMT 는 aesop 2.6.13 커널엔 없는 내용인데 제가 사용하던 2.4 커널을 참조해서 include/asm/arch/map.h 에 추가했습니다.
include/asm/arch/map.h
/*CAMIF */
#define S3C2440_PA_CAMIF (0x4F000000)
#define s3C24XX_VA_CAMIF S3C2410_ADDR(0x00800000)
#define S3C2440_SZ_CAMIF SZ_1M
#define VA_CAM_BASE S3C24XX_VA_CAMIF
#define rCISRCFMT (*(volatile unsigned *)(VA_CAM_BASE+ 0x00))
혹시나 해서 다음과 같이 rBWSCON 레지스터의 값을 찍는 코드를 추가했습니다.
camif_setup_sensor(){
printk("rBWSCON %xn",rBWSCON);
printk("rCIRSRCFMT %xn",rCIRSRCFMT);
rCIRSRCFMT |= (0x1<<31); // by lovejin
}
위와 같이 하면 rBWSCON 값은 잘 찍힙니다. (아 물론 rBWSCON 레지스터는 include/asm/arch/map.h 에 선언해 놓은 상태입니다. )
rBWSCON 값을 읽기도, 쓰기도 잘 되는데 rCIRSRCFMT 레지스터는 읽기도 쓰기도 안되고 커널 패닉이 발생합니다.
혹시 원인이 무엇일까요?
/*CAMIF */
#define S3C2440_PA_CAMIF (0x4F000000)
#define s3C24XX_VA_CAMIF S3C2410_ADDR(0x00800000)
#define S3C2440_SZ_CAMIF SZ_1M
#define VA_CAM_BASE S3C24XX_VA_CAMIF
#define rCISRCFMT (*(volatile unsigned *)(VA_CAM_BASE+ 0x00))
이 부분이 실제 커널에 적용이 되도록 MMU 세팅을 해주셔야 할겁니다.
매핑이 안되어 있으므로 패닉이 발생한 듯 싶습니다.