2012-03-10 3 views
3

먼저 디버깅 팁을 찾고 있습니다. 어떤 사람이 코드의 한 줄을 바꾸거나 문제를 해결하기 위해 설정할 주변 장치 설정 비트 하나를 지적 할 수 있다면 그것은 대단 할 것입니다. 그러나 그것은 내가 바라는 바가 아닙니다. 디버깅에 대한 자세한 내용을 찾고 있습니다.ARM 리눅스 커널 (msleep())을 디버깅하는 방법?

Google 검색 "msleep hang linux kernel site : stackoverflow.com"은 13 개의 대답을 내고 있는데 아무 것도 나오지 않으므로 묻는 것이 안전하다고 생각합니다.

임베디드 TI AM1808 ARM 프로세서 (Sitara/DaVinci?) 용 ARM Linux 커널을 재구성합니다. 모든 부트 로그가 login : 프롬프트에 직렬 포트에서 나오지만 로그인을 시도하면 응답이 없으며 입력 한 내용이 표시되지 않습니다.

많은 디버깅 후 커널에 도착하여 828과 830 사이에 디버깅 코드를 추가했습니다 (커널 버전은 2.6.37).

http://lxr.linux.no/linux+v2.6.37/init/main.c#L815

오른쪽 전에 라인 (830) 나는 영원히 루프의 printk를 추가하고 난 결과를 볼 : 'sbin에/초기화'가 호출되기 전에이 커널 모드에서이 지점에있다. 나는 약 2 시간 동안 뛰게하고 약 2 백만 건으로 계산한다. 샘플 라인 :

dbg:init/main.c:1202: 2088430 

따라서 문제없이 6000 만 바이트가 누출되었습니다.

그러나 루프에 msleep (1000)을 추가하면 msleep()이 반환되지 않고 한 번만 인쇄됩니다.

세부 사항 : 위에서 설명한 영원히 테스트 루프의 시작에서 설정 얻을 플래그에 조건이 응답 할 때 일정() 더 이상이라는 것을 보여줍니다하는 스케줄러에 라인 4073에서 조건부의 printk 추가 :

의 .config에서

http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4064

유일한 선택은/'장치 드라이버'입니다 차단 장치 I2C 지원 SPI 지원

커널과 램 디스크 loade 있습니다 d uboot/TFTP를 사용합니다. 이더넷을 사용하려고하지 않습니다. 이 모든 것이 '/ sbin/init'이전에 발생 했으므로, 거의 일어나지 않아야합니다.

세부 정보 : 동일한 CPU를 사용하는 보드가 매우 비슷합니다. 나는 같은 uImage와 같은 램 디스크를 실행할 수 있으며 거기서 잘 작동한다. 나는 로그인 할 수 있고 평범한 일을한다.

메모리 테스트를 실행했습니다 (총 64MB, 커널을 32M로 제한하고 다른 32M을 테스트, 단일 칩 DDR2). 아무런 문제가 없습니다. 하나의 보드가 UART0과 다른 UART2를 사용하지만 부팅 로그가 둘 다 나오기 때문에 문제가되지 않습니다.

모든 디버깅 정보를 제공해 주시면 대단히 감사하겠습니다. 적절한 JTAG가 없으므로 사용할 수 없습니다.

+0

스케줄러가 일부 하드웨어 타이머에 의존 할 수 있습니까? 어쩌면 고장 났을까요? 또는 다른 io 주소를 사용합니까? –

+0

내가 아는 한, 모든 것이 칩에 있어야한다. (나는 이중 값 체크를할만한 가치가있다.) 그래서 직렬 포트를 제외하고는 모두 동일한 환경을보아야한다. (모두 3 개가 활성화되어 있어야하며, 어느 것이 활성 상태인지 선택해야한다.) 타임 틱 IRQ를 찾아 거기에 printk를 추가하십시오. (찾을 수 있다면 :) – user1261470

답변

0

msleep이 돌아 오지 않거나 schedule이되면 디버그하기 위해 호출 스택을 따라갈 수 있습니다.즉 확인하는 한 가지가 그래서

msleep는 기본 케이스에 넣어 전달의 jiffies에서 타임 아웃이 < 0이면 일정을 호출하지 않고 종료 schedule_timeout(timeout)를 호출 schedule_timeout_uninterruptible(timeout)를 호출합니다. timeout가 양

경우, setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);schedule를 호출하기 전에 __mod_timer(&timer, expire, false, TIMER_NOT_PINNED); 다음에 호출됩니다.

schedule에 도달하지 못하면 setup_timer_on_stack 또는 __mod_timer에 무엇인가가 발생해야합니다.

setup_timer_on_stack의 calltrace는 CONFIG_DEBUG_OBJECTS_TIMERS가 활성화되어 있으면 init_timer_on_stack_key 호출 통화 setup_timer_on_stacksetup_timer_on_stack_key 어느 외부 또는 __init_timer(timer, name, key) 하였다 debug_initinit_timer_key(timer, name, key); 호출을 호출한다.

__mod_timer 첫 번째 호출은 timer_stats_timer_set_start_info(timer);이고 다른 많은 함수 호출이 있습니다.

setup_timer_on_stack 전화 나 __mod_timer 통화 중 어느 쪽이든간에에 printk 또는 2를 넣는 것이 좋습니다.

+0

그건 내가 씹을 수있는 톤입니다. 고마워, 그리고 다시보고합니다. – user1261470

+0

은 'schedule();'주변에 'before'와 'after'를 추가했습니다. http://lxr.linux.no/linux+v2.6.37/kernel/timer.c#L1477 항목에 printk 일정 종료(); : http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4073 http://lxr.linux.no/linux+v2.6.37/kernel /sched.c#L4152 – user1261470

+0

"두 보드에서 모두"전에 보았습니다. 본 일정() 게시판에서 나쁜 게시판과 게시판에 두 번씩 게시판을 보았습니다. 또한 참조 : 컨텍스트 스위치는 우리가 그래서 난 일정을 추측 아래에서 스택을 뒤집어 한 http://lxr.linux.no/linux+v2.6.37/kernel/sched.c#L4133 () 반환 다른 곳으로 가면 세 번째 시간 만 내 슬립프 호출로 돌아갑니다. 그래서 질문은 msleep()을 호출하는 작업이 다시 스케쥴 될 준비가되지 않았거나 CPU가 충돌 한 것입니다 (적어도 공황 메시지 일 것이라고 생각했습니다). – user1261470

0

이 문제는 해결되었습니다.

prink를 자유롭게 사용하면 schedule()이 실제로 다른 작업 인 유휴 작업으로 전환되는 것으로 확인되었습니다. 이 예에서, 임베디드 리눅스는 원래의 코드베이스를 복사하여 설치 한 유휴 작업입니다. 그 유휴 작업이 내 보드에 적절하지 않은 것 같아서 CPU를 잠 가서 충돌을 일으켰습니다. 유휴 작업으로 문제를 해결

http://lxr.linux.no/linux+v2.6.37/arch/arm/mach-davinci/cpuidle.c#L93

작품을 호출을 주석.

+0

당신과 같은 문제가 생기고 보드가 msleep 전화를 끊지 만 수정하지 못했습니다 .... "schedule_timeout"아래에서 일정()을 주석 처리 했습니까? –

+0

내가 말했듯이, 나는 유휴 작업에 대한 호출을 주석 처리했다. Linux 브라우저에는 http://lxr.free-electrons.com/source/arch/arm/mach-davinci/cpuidle.c?v=2.6.37#L93이라는 새 URL이 있으며 주석 처리 된 줄은 다음과 같습니다. 'cpu_do_idle();' –