여전히 안되고 있다-_-;;;

흑.. 앞글에서 고쳤던 부분은 원래 것이 맞았고…

loadandrun에서 dsplink쪽의 라이브러리를 쓴다는걸 생각 못해서 한창 삽질까지;;;

후.. 정말… 하나도 나아진게 없군…

일단 죽는 지점이 PROC_Attach() 할때, PROC_Invoke()의 3번재 ioctl()에서라는 거 까진 알겠는데…(이것도 추측;;;)

이것도 다른 일로 인해 보류;; 흠.. 언제쯤 성공할라나….

된건가?-_-

흠.. 일단은 dma_alloc_cohernt() 쪽 보다 일전에 함수 인터페이스가 달라서

수정했던 부분이 의심스러웠다.

(왜냐면… 전자는 모듈 로딩시 호출이 되걸랑… 그얘기는 일단 모듈은 올라갔으니까 그 부분은 문제가 없을 가능성이 높단 얘기지..)

그래서 전에 고쳤던 부분을 찾아봤다. remap_page_ranage().

음… 먼가 메모리 관련된거 같긴한데;;;;

암튼 전에 고친 것은 첫번째에 파라메터가 추가 되었고, 그 타입이 나머지 파라메터를 넘길때 쓰는 구조체와 같아서, 그냥 나머지 파라메터를 넘길 때 쓰던 그 파라메터를 넘겼었다. 좀… 아닌가? 하는 생각이 들어서…

2.4와 2.6의 두 함수를 비교해 봤다.

거의 내용이 같았는데… 2.4에서는 current라는 변수를 쓰는 곳에 2.6에서는 새로 추가된 파라메터를 이용하고 있는 것이 아닌가…

그래서 전에 고쳤던 부분에서 첫번째 파라메터를 current로 바꿔 주었다.

그리고는 컴파일..

평소처럼 RELEASE에 만들어진 것을 복사할려다가 문득, DEBUG로 하는게 낫지 않을까 싶어, DEBUG로 들어가서 ko파일을 만든 다음 rootfs로 복사했다.

그리고는 모듈을 로드하고 loadandrun실행. 헛… 죽진 않는데 이건 전에 봤던 그 80008008 에러-_-;

다시 원점인가… 라는 생각이 들다가 RELEASE로 다시 해봐야 겠다는 생각이 들었다. 흠.. WARRNING이 두개 뜨고… 어라… 모듈 로드가 안되네… -fno-common 옵션을 주고 컴파일 하란다. (전에 넣었다가 dma_alloc_cohrent를 쓰는 과정에서 삭제 했었다.)

다시 넣어서 하니 깔끔하게 컴파일 & 모듈 로딩.

그리고 loadandrun을 실행.

어라… 에러는 안나는데… 먼가 찝찝한…. rtaTrace를 실행시켜도 별 반응도 없고..-_-;

이건 된거 맞긴 한가?-_-;;

일단 한 걸음..

산 넘어 산의 연속이지만… 암튼 일단 한 걸음 전진…

처음에는 consistent_alloc() 대신 consistent_sync()를 써서 작동하도록 dsplink 소스를

고쳐 볼려고 했다.

흠.. 근데 이게 만만치가 않네… consistent_sync()를 쓸경우, 해당 메모리에서 읽고 쓸 때마다,

함수를 호출 해줘야 하는데… 이게.. 따라 가다 보니 영..-_-a

그래서 일단 consistent_sync()를 쓰는 부분을 그냥 메모리를 할당하도록 하고 함 돌려 봤다.

일단 모듈은 무사히 올라가는데… 허걱… loadandrun을 실행하니까 먼가 엄청난 메시지를

뱉으면서 죽어 버린다..-_-; 커널에 디버깅 옵션을 켜놔서 레지스트리랑 메모리 내용을

출력해주는 거 같다. 대충 paging 요구를 처리하지 못했다는 내용이네…

움… 결국 고쳐야 하나… 아님 2.4 소스에서 consistent_alloc()을 가져다가 넣어 버릴까?-_-

역시 가장 쉬운 해결 방법은….

커널 2.4로 하는건데;;;;;

쩝.. 일단은 좀더 해 보자 싶어서 소스를 여기 저기 뒤적이다가…

계속 들던 의문… consistent_alloc()이 왜 2.6에 와서 사라졌느냐는 거다.

거기다 더 이상한건 저 함수들이 보이는 아키텍쳐는 arm, ppc(?PowerPC), sh(?SuperH)뿐이라는 것…

일단은 우리의 친구 구글에서 consistent_alloc을 쳐 봤다.

오호.. 재수가 좋은 건가.. 첫번째 질문이 나랑 비슷한 처지인거 같았다.

이더넷 디바이스 드라이버를 2.4에서 2.6으로 포팅하는데 consistent_alloc() 땜에 곤란해

하고 있는 듯 했다(아마도-_-)

그에 대한 답변중에 Russell King이라는 사람(아마 ARM쪽 리눅스 담당자(?) 쯤 되는 사람인거

같다. 이름도 들어본거 같고..)이 쓴 글이 있는데…

대충 consistent_alloc()은 잘못된 인터페이스를 가지고 있어서 제거할 것이며,

2.6에서는 dma_alloc_cohernt()를 쓰라는 것이다.

아! 이거다 싶더군.

그래서 당장 커널 소스를 뒤져봤다. 오… consistent_alloc()하고 약간 다르긴 한데

거의 유사하다. 파라메터 순서가 좀 다르고, struct device 타입의 파라메터가 하나 더 있다.

이걸 적당히 셋팅해서 넘겨주기만 하면 되겠군… 이라고 생각했는데… 이게.. 꽤 복잡한

스트럭쳐다-_-;

그래서 일단은 NULL을 넘겨 주기로 했다;;;(저거 가지고 하는 것도 별로 없어 보이더라고-_-)

일단 예의 그 부분을 고치고… 컴파일, insmod, 그리고…

젠장… 상태가 아까 보다 더 심각하다… 아예 다운 되버리는군-_-;;;

끙… 좀더 수련이 필요할 듯 하다;;;

(아님 진짜 2.4로 하던가-_-)

consistent_alloc() & consistent_sync()

아아.. 간신히 정체를 조금 알았다.

모든 문제는 DMA가 CPU를 거치지 않고 메모리를 읽고 쓰기 때문…

예를 들어 디바이스에서 메모리에 데이터를 쓴 경우, CPU가 그 주소에 대한

캐쉬를 가지고 있다면 CPU는 엉뚱한 데이터를 읽게 되는 것이다.

이를 해결하는 방법은 2가지.

하나는 CPU가 그 메모리 영역에 대해서는 캐쉬를 쓰지 않게 하는 것이고,

또 하나는 디바이스<->메모리 간의 데이터 이동이 일어나거나 일어난 후,

CPU의 캐쉬와 메모리를 동기화 시켜 주는 것이다.

전자에 쓰는 함수가 consistent_alloc()이고 후자에 쓰는 함수가 consistent_sync().

즉, consistent_alloc()과 consistent_free()가 없더라도, 원하는 바는 달성할 수 있지만… 좀더 복잡해 진다.

consistent_alloc()과 consistent_free()는 메모리 할당/해제시에 한번만 해주면 되지만,

consistent_sync()의 경우에는 디바이스에서 메모리를 읽기전이나,

디바이스에서 메모리에 쓴 후에 일일이 consistent_sync()를 호출해 줘야 된다.

흠… 결국…. dsplink소스를 다 뒤져서 해당 부분마다 consistent_sync()를 호출해 줘야 한단 말인데;;;

원격 리셋

OSK를 컴에 설치하고, 원격에서 그 컴에 접속해서 작업을 하는경우,

다른 건 문제가 없는데… OSK를 리셋해야 하는 경우가 생기면 참으로 난감하다.

리눅스에서 리붓을 해도 다시 부팅 되지는 않고…

플래쉬에서 부트로더를 읽은 담에 메모리에 쓰고, 거기로 점프시켜버리는 무식한 방법도 있을꺼 같고..

승훈이 말로는 watchdog-timer를 쓰면 가능할꺼라네….

암튼.. 한 번 시도해봐야 겠음..

삽질의 연속..

장문의 글을 썼으나 날려먹은 관계로 간단히 요약.

수요일… init의 실행이 안되는 것이

  1. 실제로 init이 없음
  2. init이 필요한 공유라이브러리가 없음
  3. init이나 공유라이브러리의 퍼미션이 잘못 되었음

중의 하나임을 http://kelp.or.kr에서 알아냄.

busybox에서 파일을 찾을 수 없다고 하는 것도 init과 같은 경우가 아닌가 생각하여 공유라이브러리를

복사하고 실행하였으나 같은 결과….

토요일…공유라이브러리를 몽땅 /lib에 복사. 실행 성공. 공유라이브러리에서 필요로 하는 다른 공유라이브러리가 없어서 실행이 안됐던 것임

loadandrun을 실행하면 80008008 에러가 나며, 에러의 내용은 ‘일반적인 오류 발생’.

모듈을 올리지 않아도 같은 에러로 가는 걸로 봐서 모듈이 제대로 작동하지 않는 것으로 보임.

모듈을 새로 컴파일하자 consistent_alloc()과 consistent_free()가 없다는 오류가 나고 모듈이 올라기지 않음. -fno_common을 추가하여 컴파일하라고 하지만 상태는 같음.

해당 함수는 일반적으로 asm/io.h에 선언되어 있으나, 2.6의 asm-arm/io.h에는 없음. 위의 두 함수와 같이 선언되어 있던 consistent_sync()는 2.6의 dma_mapping.h에서 발견. 그러나 역시 방법이 없음.(아마 이 함수들은 DMA와 관련하여 메모리 할당/해제에 쓰이는 거 같음)

결국 두 함수를 쓰는 부분을 주석처리 하고 올려봤으나 허가되지 않은 동작이라면서 올라가지 않음. 그리고 리셋을 할때 까지 해당 모듈 리소스가 사용중이라는 메시지와 함께 insmod가 계속 실패함.

===

쩝.. 아깐 이거 보다 더 잘적었었는뎅..T-T

갈길이 멀다

흐.. 쉬운게 없구나..

어제 드디어 dpslink를 돌려 볼려고 했다..

근데… 덴장… 이놈의 모듈들은 올라가지도 않고… loadandrun 이라는 DSP 쪽 로더로 보이는

넘은 실행도 안된다.(분명 파일이 있는데 자꾸 그런거 없단다.)

2.4 커널로 부팅해서 해보니, 여전히 loadandrun은 안되는데 모듈은 로드가 된다. 약간의

메시지가 출력되긴하지만..

아무래도 2.4대와 2.6대의 커널 모듈이 좀 다른듯 하다.. 단순히 확장자만 다른게 아니었단 말인가;;

(2.6에서 올릴려고 해보면 올바른 포맷이 아니라고 나온다)

일단은 모듈을 2.6에 올리는 작업부터 하기로 했다. 리눅스 커널 모듈 프로그래밍을 해 본적이

없는 나로써는 그야말로 앞이 깜깜했다.. 그래도 어쩌겠는가.. kldp로 가서 열심히 찾아보았다.

그래서 발견한 곳이

역시나 2.4에서 2.6으로 바뀌면서 변경된 부분이 많덴다..

일단 문서에 나왔있는 hello, world 모듈을 만들어서 PC에 올려보고…

OMAP에도 올려봤다.. 그런 대로 동작하는 듯 하다.

(이때, makefile은 커널 소스에 있는걸 땡겨 쓰는것 같은데 좀 어려워 보여서 그냥 썼다.)

이제 모듈 두 개를 2.6용으로 새로 만들어야 하는데… 이것참 막막하다-_-;;

dsplinkk.o 를 만드는 소스 쪽에서 모듈 초기화 등등의 인터페이스가 구현된 부분을 찾으려고 했는데..

도저히 못찾겠다. makefile도 분산되어서 여기저기서 include하기 땜에 복잡고 @_@

그래서 일단 pmr_drv.o 라는 넘을 바꿔보기로했다.

이넘은 미리 컴파일 되서 제공되는데… 다행히 소스가 rta_sdk_5_00/ti/bios/rta/sdk/src/pmrdrv에

있었다.

일단 모듈 인터페이스 부분을 고칠려고 봤더니.. 2.6 에서의 형식으로 되어있었다…

흠.. 전에도 썼던 방식인가… 그럼 컴파일만 새로 해보자…

음.. 근데 어떻게 해야 될지 잘몰라서… 일전의 예제에서 썼던 makefile을 복사해다가 수정해서 썼다.

그리고 make…

오호.. 일단은 pmr_drv.ko 라는 파일이 생겼다.

이걸 OMAP에 올려서 insmod를 하니까 문제 없이 올라간다.

흐흐.. 좋았어.. 다음은 다시 dsplinkk.

흠.. 근데 이게 좀 곤란하다.. 도저히 못찾겠다.

그때, 문득 꽁수가 떠올랐다. pmr_drv도 모듈인터페이스는 2.6방식이었으니까, 이놈도 그럴꺼다.

그리고, 앞의 두 경우를 봤을때, .ko 파일은 .o 파일을 바탕으로 만들어지는 듯 하다…

그렇다는 것은…..

커널의 makefile을 잘 이용하면 현재 만들어진 .o 파일을 .ko로 바꿀수 있지 않을까…

그래서 일전의 makefile을 복사하고, 더미로 dsplinkk.c 라는 파일을 만들고,

아무것도 안하는 dsplinkk.c 타겟을 makefile에 추가하고.. make!

오호.. 그 결과 dsplinkk.ko가 생겼다. 이걸 OMAP에 올려보니 잘 올라가는군 :)

근데 이게 진짜 제대로 만들어진 건지는 알수 없다. ;;;

방법은 예제를 돌려보는 것…

그러려면 일단 loadandrun 이 돌아가야 하는데…

아무래도 이게 실행이 안된다.. 그래서 고민하다가 OMAP의 파일 시스템을 둘러보던중…

웃…. 모든 명령이 busybox에 심볼릭 링크로 걸려있다.

이게 도대체 먼가;;;

이런저런 실험을 해본결과… 내가 얻은 결론은 이렇다.

이 루트 파일시스템에서 실제로 실행이 되는 파일은 busybox 밖에 없다.

(아.. busybox라는 넘은 유닉스계열에서 쓰는 웬만한 명령은 모두 내부 명령으로 포함하고 있는

작은 크기의 유용한 프로그램이다.)

그리고 나머지 명령들은 모두 busybox에 심볼릭 링크로 걸려있다. 그래서 각 명령을

실행하면 실제로는 busybox가 실행되면서 해당 명령을 수행한다.

예를 들어 ls를 실행하면,

실제로는 busybox가 실행되고, 이때 main()의 아규먼트 중 첫번째인 실행파일명은 ls가 된다.

busybox는 이를 이용해 ls 기능을 수행하고 결과를 보여준다.

아아.. 놀랍지 않은가… 쉘 내부 명령으로 처리한다기 보다는

실제로 busybox를 하나 더 실행하면서 파라메터로 수행해야되는 기능명을 넘겨서

해당 기능을 수행하는 것이다.

그건그렇고.. 그래서 도대체 왜… 그외의 외부 파일은 실행이 안되느냔 말이다-_-;

busybox의 소스를 뜯어고칠까도 생각했지만… 일단 기본 쉘을 bash로 바꾸면 간단할 거 같았다.

애당초 쉘로 busybox가 실행되기 때문이니까…

그래서 bash의 소스를 구해서 컴파일하고, 올려보았다.. 어라.. 근데 이게 잘 안된다..

그래서 요리조리 해보던중… 두둥…. init 마저도 busybox의 심볼릭 링크 였다-_-;

이렇게 되면 init도 새로 설치하고 만다~

그래서 이리 저리 해서 컴파일하고, 설정하고, 올렸는데…

이런이런… 부팅이 안된다-_-;

아씨.. 수련이 부족하다… 좀더 수련을 쌓아서 다시 도전해야겠다;;;

DSP/BIOS LINK 컴파일 성공

끙… 간신히 컴파일에 성공.

몬타비 스타 리눅스 깔아 볼랬더니…

패스워드 암만 쳐도 안되고..-_-;;;

해서 고민 하다가 결국…. make 파일을 뜯어 고치기 시작…

흠… 보니까 생각 보다 쉽더군…

딴게 아니고… 몬타비스타 리눅스에 포함된 툴체인 쪽으로 패스가 지정되어 있는 거두만..

그래서 그걸 우리의 gcc 툴체인쪽 패스로 변경…

문제 없이 잘되는 듯 하다가… 난데없이…
    current->prio

란 부분에서 prio가 스트럭쳐의 멤버가 아니라네;;;;

도대체 먼지…. 어디의 머하는 넘인지도 모르겠고…

여기저기 뒤져서 간신히 linux/sched.h 에 정의된 task_struct 라는거 까지 알았는데…

암만 봐도 멤버에 prio가 있거든;;;

결국 저 부분을 0으로 변경해서 일단 컴파일 통과~

방금은 ARM 쪽 DSP/BOIS Link였고.. 다음은 DSP 쪽…

흠.. 이쪽 make 파일도 가이드를 참조해서 수정하니.. 약간의 시행착오 뒤에 손쉽게 성공.

자.. 이제 남은 건 예제를 돌려 보는….

그러려니 OSK를 설치 해야 되잖아… 귀찮쿠로..-_-;;

그래서 일단 테스트는 다음으로 넘기고….

아까 문제의 prio 를 해결하기로 결정.

흠… 여기 저기 뒤적이다 보니 문득 생각나는게…

툴체인에서 리눅스쪽 헤더를 쓸때 어디껄 땡겨쓰지?

호스트의 리눅스 헤더는 아닐꺼 같고…. 흠…..

아… 툴체인 디렉토리 밑에 arm-linux란 디렉토리가 있었지.

음.. 역시… arm-linux/sys-include 를 확인하니 리눅스 헤더가 있군.

근데 여기 있는 linux/sched.h를 보니 prio 가 없다!!

대신 nice가 있네… 이건 2.4에 해당 사항인거 같은데…

아마 툴체인에 포함된 헤더가 2.4 인듯…

해서… omap용 리눅스 커널 소스에서 헤더를 가져다가 (심볼릭 링크) 다시 컴파일 해보니

문제의 prio 부분은 무사 통과….

근데 remap_page_range() 라는 함수의 파라메터 갯수가 DSP/BIOS Link 소스하고 헤더에 정의 된게 다르다..-_-;;

끙… 일단 첫번째에 파라메터를 추가한 다음에 다시 컴파일 하여 일단 작성은 성공.

자… 오늘은 여기까지 하고 나머지는 다음 번에…