커널단에서 init_timer 이용해서 timer 돌리는데요. 자꾸 에러가 나요

jgm2000의 이미지

init_timer 이용해서 add 해주고 expires, func 선언 다 해주었습니다.
타이머는 잘 돌아가는데요.
func에서 sys_open을 해 놓게 만들었습니다.
일정 시간 지나면 sys_open을 호출하게요.
근데 sys_open을 하게되면 커널 에러가 뜨면서 리눅스가 죽어버려요.
func 내에서 sys_open 호출 안하고 다른 루틴에서 호출하면 안죽거든요.
유독 timer 내의 func에서 호출할때면 죽네요?
원인이 뭘까요?
아시는 분 계시면 답변 부탁드립니다.

익명사용자의 이미지

sys_open 은:
asmlinkage long sys_open(const char __user *filename, int flags, int mode)

이므로 sys_open에 전달하는 첫번째 인자는 포인터가 user's address space를 가리키는 포인터여야 합니다.
그냥 커널 주소를 가리키는 포인터를 사용하시면 엉뚱한 주소값을 접근하게 되서 커널이 죽겠지요.

jgm2000의 이미지

set_fs(KERNEL_DS)를 해주는데도 그런가요?
sys_open을 커널 모듈에서 잘 썼었거든요.
문제는 timer에 등록된 함수에서 사용할 때만 이런 에러가 나는건데요.
해결법이 없을까요?
static int myserial_open(void)
{
old_fs = get_fs();
set_fs(KERNEL_DS);
handle = sys_open("/dev/ttyUSB0", O_RDWR, 644);
if( handle < 0 ) {
handle = 0;
set_fs(old_fs);
printk("Serial Open Fail [%s]\n", device_name);
return -1;
}
else {
printk("Seial Open Success....\n");
filep = fget(handle);
ttyp = filep->private_data;
filep->f_pos = pos;
return 0;
}
}

void time_func(unsigned long key)
{
if( key == 777 )
{
printk("timer....%d\n", timeseq++);
init_timer(&usngw_mod_timer);
usngw_mod_timer.expires = get_jiffies_64() + 5 * HZ;
usngw_mod_timer.data = 777;
usngw_mod_timer.function = time_func;
add_timer(&usngw_mod_timer);
}

if((myserial_open()) < 0)
printk("Serial Open Failure...\n");

}

이렇게 했는데 myserial_open 해서 커널 에러가 나는 거 같습니다.

익명사용자의 이미지

타이머에서 open 같은 호출을 하는 것은 위험합니다. (중간에 대기 상태로 빠질 수도 있으므로..)
대기 상태를 허용하는 kernel thread를 사용하시는 편이 좋을 것으로 보입니다. (thread loop내에서
필요한 시간만큼 wait를 주어 타이밍을 맞출 수 있습니다.)

jgm2000의 이미지

int kwdtd(void *unused)
{
daemonize();

for (;;)
{
printk(KERN_DEBUG "What's going on, kernel!\n");
schedule_timeout(2);
}
}

int init_module(void)
{
kernel_thread(kwdtd, NULL, 0);
printk(KERN_DEBUG "Hello, kernel!\n");
return 0;
}

void cleanup_module(void)
{
printk(KERN_DEBUG "Good-bye, kernel!\n");
}

님 말씀대로 kernel thread를 이용해서 할려고 위에 예제를 이용했는데요.
daemonize에서 인자가 더 필요하다고 나오네요
커널 2.6대를 쓰는데 실제로 linux/sched.h 에 들어가보니 daemonize에 인자가 있던데
여기 들어가는 인자들은 무엇인가요?

bushi의 이미지

timer 핸들러는 인터럽트 컨텍스트입니다.
구현마다 다를 순 있겠지만, OS tick timer 인터럽트에서 호출됩니다.

커널 쓰레드를 따로 만드시는 것이 속 편하긴하나,
그와 같은 반복작업을 피하고자 만들어진 설비들이 있습니다.
2.4 에서는 약간 부족한 감이 있으나,
2.6 으로 올라오면서 이름이 바뀌면서 편의설비들이 추가되기도 했습니다.

올려주신 소스가 불완전하여 정확한 판단은 어렵지만,
여러가지 부적절한 점이 있는 것 같기도 합니다.

daemonize() 의 구현은 kernel/exit.c 에 있으며,
아규먼트는 쓰레드의 이름입니다.
daemonize("kkldpd");
daemonize("kkldpd_for_%s@%lu", UTS_RELEASE, jiffies);

prether의 이미지

윗 분 말씀마따나 kernel dynamic timer는 IRQ context에서
동작하므로 시스템 콜을 부르면 문제가 발행합니다.

queue_delayed_work()를 써봄이 어떨까요?

kernel thread 방식으로 돌고 패러미터로 delay time을 입력할 수 있습니다.

/***************************************
Being the one is just like being in love.
***************************************/

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.