리눅스 커널 영역에 전역 변수를 정의 하려면

mandugukbap의 이미지

Linux 3.2.x 커널을 이용해 개발 중입니다.

- 커널 영역에 새로운 시스템콜을 만들었습니다. 예) sys_test_call(char* msg)

- 유저 영역에서 해당 시스템콜을 불렀습니다. 예) syscall(359, "Hello");

- 유저 영역에서 건너온 msg(예제에선 "hello")를 커널 영역의 전역 변수에 저장하고 싶습니다.

질문: 보통 커널 프로그래밍을 할 때 전역 변수는 어느 부분(파일)에 정의를 하는가요? 실제 프로젝트에서는 TCP/IP 스택에서 넘겨 받은 정보를 사용할 예정입니다.

감사합니다.

익명 사용자의 이미지

안녕하세요...아래 말씀드린 익명입니다.
컴없이 지낸세월이 10년 넘어서리 구체적인 답안은 못드리겠고 스마트폰으로 커널소스 보기도 어렵고...제 맘대로 떠들어 볼께요.

" - 유저 영역에서 건너온 msg(예제에선 "hello")를 커널 영역의 전역 변수에 저장하고 싶 습니다.

질문: 보통 커널 프로그래밍을 할 때 전역 변수는 어느 부분(파일)에 정의를 하는가요? 실제 프로젝트에서는 TCP/IP 스택에서 넘겨 받은 정보를 사용할 예정입니다."

커널내 전역변수라면 커널 코드-데이타-스택 중 데이타 안에 이 변수가 들어가야 하는데 언뜻 그게 왜 안될까 해서 잠시 검색해봤더니 사용자 영역과의 io 함수는 모두 asmlinkage 가 스택에 위치하게끔 바꿔버린다네요. sys_open 같은 이미 있는 함수도 보니 여지없이 이케 되어 있습니다.
이걸 떼고 extern 으로 한다든가 하는 방법이 있는지는 모르겠으나 거기까진 못들어가겠고 일단 커널 tcp/ip 동작을 예로 보죠(이걸 하시려니까)

음..
사용자가 소켓을 열면 시스템콜이 들어가고 이 시스템콜의 인자로 msg 를 전달해서 커널 내부에서 전역변수로 쓰는건 현재 막혀있죠 대신 시스템 함수 안에서 인자를 주어 다른함수를 호출하고 그 호출받은 함수에서 전역으로 복사를 하면 되지 않을까요
이 '다른 함수' 가 문제인데
소켓의 경우 커널에서는 write 로 남어온걸 skb 로 복사합니다.다만 커널입장에서는 유저 vm 과 실제 물리를 자기가 관리하기에 사용자영역 메모리주소에서 직접 커널 데이타영역 주소로 복사할 수 있습니다.아마 이게 맞을겁니다.
바꿔 밀하면 msg 같은 간단한 문자열같은 경우 별 문제가 없을 것으로 예상되는바 따로 파일을 만들지 마시고 sock 이나 skbuff 안에 함수를 하나 추가하시면 어떨까요
소켓호출시 하실건지 아님 쓰기호출시 하실건지에 따라 커널 시스템 함수 내부의 점프를 보시고 그 점프 함수속에다 집어넣으면....ㅠㅠ

저번에 여러가지 심각하게 알아야 가능하다고 말씀드린건 이런식의 시도인줄 몰랐기 때문이고요 또 웬만하게 원하는 기능은 이미 커널속에 구현되어 있는데 뭔가 고치신다기에 tcp/ip 루틴을 탈탈 털어보시려나 보다 했지요...
참고로 하시려는게 이미 있는것으로 가능한지 sk_buff 구조체를 함 보시면 어떨까 말씀을 드립니다.

mandugukbap의 이미지

명확한 설명 주셔서 정말 감사합니다.

일반 프로그래밍처럼 전역 변수를 사용하는게 커널에서는 쉽지가 않군요. 말씀해 주신대로 다른 함수를 호출해서 데이터를 복사하는 방법을 이용해야 할 것 같습니다. 아니면 다른 방법이 있는지 고려를 좀 해 보아야겠습니다.

알고 있는 바로는 sk_buff 구조체에 필요한 멤버가 포함되어 있지 않습니다.

커널로 넘기고자 하는 정보는 넘겨지는 즉시 사용되는 것이 아니라 t시간 후 또는 k연산 후에 (실제로는 약 1ms 뒤에)에 참조되고 버려질 것이기 때문에 그리고 데이터를 받는 시스템콜(또는 디바이스 드라이버) 안에서가 아닌 TCP에서 사용할 정보이기 때문에 전역 변수를 생각했었는데, 이런 경우에 일반적으로 사용하는 코드 기법이 있는지 모르겠네요.