시스템관리자의 쉼터 커피닉스 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

가입없이 누구나 글을 쓸 수 있습니다. 공지사항에 대한 댓글까지도..




BBS >> 설치, 운영 Q&A | 네트웍, 보안 Q&A | 일반 Q&A || 정보마당 | AWS || 자유게시판 | 구인구직 || 공지사항 | 의견제시
블록 디바이스 드라이버와 sys_call에서요..

 
글 쓰기   답변 달기    커피닉스, 시스템 엔지니어의 쉼터 게시판 인덱스 -> *NIX 일반
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
dukedrum
손님





올리기올려짐: 2007.10.09 화, 1:20 pm    주제: 블록 디바이스 드라이버와 sys_call에서요.. 인용과 함께 답변

아..요즘 램디스크 예제를 변형해서 프로그램 짜보려는데... 제가 커널에 대해
잘 몰라서 그런건지 원인 모를 에러가 발생하네요...

IT EXPERT 책중에 리눅스 커널 프로그래밍이나 디바이스 드라이버 책에 나오는
램디스크 예제를 변형 하려고 합니다.

램디스크는 메모리에 vmalloc으로 공간을 할당해주고 make_request를 통하여
해당 작업(read,write 등..)을 수행 해주는데요..

저는 메모리 공간이 아닌 User영역의 파일을 Open하여 메모리 대신 그곳에 저장을 하려 합니다.

현재 sys_call_table을 찾아서 파일에 open,read,write,close,lseek까지 전부 다
되고있는 상태입니다.

소스를 제가 생각 한데로 변경 하여 실행했더니 mke2fs로 포멧하여
파일의 용량이 4MB로 바뀌고 mount까지 성공을 했습니다.

그런데 mount이후에 ls나 mv, cp 등등 뭔가 작업을 수행하려고 하면 해당 터미널이 뻗는 현상이 나네요..ㅠㅠ

분명 memory영역에 잘되던 소스...
추측은 make_request와 syscall(사용자영역)간의 문제가 아닐까 하는 생각이
들긴 하지만... 뚜렸한 원인을 못찾고 있습니다..

밑에 중요 부분(make_request)의 소스를 올립니다.
고수님들의 조언 부탁합니다...ㅠㅠ(벌써 이걸로 3주째 고생..)

///////////파란색 부분은 기존의 소스,녹색은 제가 변경한 소스///////////

static int vrd_make_request(request_queue_t * q, int rw, struct buffer_head *sbh)
{
unsigned int minor;
// char *pData; // 메모리의 위치를 저장할 포인터변수 /**/
int nFileDesc = 0; //Open된 파일의 디스크립터 저장
int nFilePointer = 0; // lseek로 이동 시킬 파일의 포인터 이동값 저장
mm_segment_t old_fs; //

old_fs = get_fs(); // 현재의 범위 저장
set_fs(KERNEL_DS); // 커널 영역으로 범위 셋팅

nFileDesc = fn("disk.dsk",O_RDWR);
// disk.dsk 파일을 읽고 쓰기 권한으로 Open(sys_call)


minor = MINOR(sbh->b_rdev); // 부번호 얻기

if( minor >= VRD_MAX_DEVICES ) goto fail; // 부번호의 값이 최대 장치 수보다 크면 에러 표시
if( ( (sbh->b_rsector*VRD_SECTOR_SIZE) + sbh->b_size ) >= VRD_SIZE ) goto fail;
// 처리하는 디바이스에 대한 정보가 지정된 크기를 초과하면 에러

/* Memory Pointer */
//pData = vdisk[minor] + (sbh->b_rsector*VRD_SECTOR_SIZE);
// 저장시킬 메모리의 위치를 받아옴

nFilePointer = sbh->b_rsector*VRD_SECTOR_SIZE;
// 데이터를 처리할 파일의 위치 받아옴


switch(rw)
{
case READA :
case READ : printk("Read lsk is %d\t",lsk(nFileDesc,nFilePointer, 0));
// disk.dsk 파일 내에서 데이터를 처리할 위치로 nFilePointer만큼 이동
printk("<< Read file Num is %d >>\n",rn(nFileDesc,sbh->b_data , sbh->b_size));
// lseek로 이동한 위치에서 b_size 만큼 읽어 옴

//memcpy(sbh->b_data, pData, sbh->b_size); // 메모리 영역에서 읽어옴

break;

case WRITE :
refile_buffer(sbh); // 해당 버퍼의 상태를 확인해서 LRU리스트에서 버퍼 헤더의 추가/제거 여부를 결정

//memcpy(pData, sbh->b_data, sbh->b_size);

printk("Write lsk is %d\t",lsk(nFileDesc,nFilePointer, 0));
printk("<< write file Num is %d >>\n",wn(nFileDesc, sbh->b_data, sbh->b_size));


mark_buffer_uptodate(sbh, 1); // 해당 버퍼가 변경 되었으므로 업데이트 해야된다고 커널에 알림
break;
default : goto fail;
}
sbh->b_end_io(sbh,1); //커널에 정상적으로 종료 되었음을 통보

cls(nFileDesc); // 파일 닫기
set_fs(old_fs); // 원래 상태로 셋팅


return 0;
fail:

cls(nFileDesc); // 파일 닫기
set_fs(old_fs); // 원래 상태로 셋팅


buffer_IO_error(sbh); // 커널에 요청이 정상적으로 처리되지 못했음을 통보
return 0;
}

[/code]
위로
이전 글 표시:   
글 쓰기   답변 달기    커피닉스, 시스템 엔지니어의 쉼터 게시판 인덱스 -> *NIX 일반 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 있습니다
답글을 올릴 수 있습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB © 2001, 2005 phpBB Group