[질문] 커널스레드 관련하여 질문이 있어요~ ^^;
안녕하세요~ ^^;
지난번에 한번 올렸다가 답변을 못받고.. ㅠ_ㅠ
다시 시간이 생겨 질문을 드리려고 합니다...
저는 ISA 슬롯을 사용하는 여러 Device가 IRQ 공유를 통해서
하나의 IRQ를 사용하도록 했습니다....
처음엔 ISR내에서 모든 인터럽트 서비스를 해주도록 했었는데..
드라이버의 모델이 약간 바뀌면서 ISR내에서 뮤텍스 락을 해야할
경우가 생겼습니다....보통은 ISR내에서는 뮤텍스 락을 하지 않는것이
좋을것 같아서.. 원래 ISR에서 하던 기능을 하나의 커널스레드로 옮겼습니다..
커널스레드는 모듈초기화시 생성된후 ISR에서 깨워줄때가지 잠들어있구요..
ISR에서는 인터럽트가 발생하면 스레드를 깨워주고는 바로 잠듭니다...
그러면 깨어난 커널스레드는 IntStatus 값을 읽어 와서 해당하는 처리를 하고
다시 슬립하는 구조로 되어있습니다..
또 인터럽트가 발생하면 다시 스레드는깨어나고...
결국 ISR 함수는 스레드에게 일을 할수 있게하는 트리거가 되었죠.. ^^;;
그런데...스레드가 하는 기능중 하나가..
커널영역버퍼에서 유저영역버퍼로 데이터를 복사해 주는 일인데요..
copy_to_user(); 함수를 사용했습니다.. 그런데..카피가 되질 않네요..
request_irq(); 로 등록하는 루틴은..
result = request_irq(DriverEntry.jpeg_irq, jpeg_interrupt, SA_SHIRQ, "pci_jpeg", pJDTemp);
이렇게 되어있구요..
커널스레드를 생성하는 부분은
kernel_thread(KTJpegISRDaemon, DriverEntry.JpegDevice + i, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
이렇게 되어있습니다..
copy_to_user() 부분은
copy_to_user(pIntQEntJpegFile->ImgReq.pUserBuffer, pIntDeviceEntry->pJPEGBuffer, pIntDeviceEntry->HeaderImgSize));
이렇게 되어있습니다..
pUserBuffer 포인터는 read() 시스템콜에서 커널로 넘어오는 유저영역의
버퍼 포인터이구요..
pJPEGBuffer 포인터는 유저영역 버퍼에 복사해줄 데이터가 저장되어있는
커널영역 버퍼의 포인터 입니다.. 커널버퍼는 kmalloc, vmalloc,
그냥 단순한 전역변수 배열..(ㅡ_ㅡ;;)등으로 잡아봤는데 스레드에서 복사는
다 안되더군요..
jpeg_interrupt 라는 함수안에서 copy_to_user(); 를 수행했을때는
잘 됩니다. 그런데 스레드 안에서 하면 잘 안됩니다..
copy_to_user() 를 커널스레드 안해서 할 수 있는 방법을 좀 알려주세요..
늘 도움만 받고 있네요.. 그럼 행복한 하루 되세요~~~ ^^;;
일단 저도 linux kernel에 대한 건 잘 모르구요.copy
일단 저도 linux kernel에 대한 건 잘 모르구요.
copy_to_user가 안된다면, 아마도 interrupt mode에서 동작하는 것 같습니다. 그렇다면 user space 접근하는 것도 안되고, current pointer도 쓸 수 없고, sleep_on이나 schedule을 부를 수도 없는 것으로 알고 있습니다.
일단 in_interrupt()를 불러서 interrupt mode인지 확인해 보세요.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
위 cinsk 님의 답변에 대한 보충 설명입니다.소스: http:
위 cinsk 님의 답변에 대한 보충 설명입니다.
소스: http://www.xml.com/ldd/chapter/book/ch06.html
This asynchronous execution resembles what happens when a hardware interrupt happens (which is discussed in detail in Chapter 9, "Interrupt Handling"). In fact, task queues are often run as the result of a "software interrupt.'' When running in interrupt mode (or interrupt time) in this way, your code is subject to a number of constraints. We will introduce these constraints now; they will be seen again in several places in this book. Repetition is called for in this case; the rules for interrupt mode must be followed or the system will find itself in deep trouble.
A number of actions require the context of a process in order to be executed. When you are outside of process context (i.e., in interrupt mode), you must observe the following rules:
* No access to user space is allowed. Because there is no process context, there is no path to the user space associated with any particular process.
* The current pointer is not valid in interrupt mode, and cannot be used.
* No sleeping or scheduling may be performed. Interrupt-mode code may not call schedule or sleep_on; it also may not call any other function that may sleep. For example, calling kmalloc(..., GFP_KERNEL) is against the rules. Semaphores also may not be used since they can sleep.
Kernel code can tell if it is running in interrupt mode by calling the function in_interrupt(), which takes no parameters and returns nonzero if the processor is running in interrupt time.
댓글 달기