Linux - 2.6.25 커 널 프레임 버퍼 장치 구동 분석
1 Frambuffer 소개
프레임 버퍼 는 Liux 시스템 에서 상부 응용 과 바 텀 디 스 플레이 장치 사이 에 있 습 니 다. 다음 그림 과 같 습 니 다.그의 디자인 의 도 는 상부 응용 에 대해 저층 의 서로 다른 하드웨어 의 조작 디 테 일 을 차단 하 는 것 이다. 서로 다른 공장 의 서로 다른 유형의 디 스 플레이 하드웨어 에 대해 각 업 체 가 기술적 으로 장점 을 살 리 고 단점 을 피 하 는 수요 가 있 기 때문에 구체 적 인 디 테 일, 예 를 들 어 레지스터 의 수량 과 종류의 디자인 에 있어 상당 한 차이 가 존재 할 것 이다.또한 각 레지스터 의 초기 화 에 대한 정의 와 리드 신호 에 대한 정의 도 비슷 하지 않다. 이 는 두 가지 성능 이 비슷 한 제품 이라도 예 를 들 어 샤프 3.5 인치 LCD 모듈 과 삼 성의 3.5 인치 모듈 은 조작 디 테 일이 다르다.그래 픽 인터페이스 개발 에 능 한 개발 자 들 로 하여 금 하드웨어 범주 에 속 하 는 액정 모듈 레지스터 의 기록 순서 문 제 를 궁리 하 게 한다 면 큰 낭비 일 것 이다.따라서 개발 자의 시간 과 정력 을 절약 하기 위해 상부 개발 과 하부 설비 사이 에 중간 층 을 넣 어야 한다.
2 Frambuffer 디 스 플레이 원리
프레임 버퍼 는 사용자 프로 세 스 의 데 이 터 를 저장 한 다음 디 스 플레이 장치 에 입력 하 는 저수지 와 유사 합 니 다.사용자 에 게 프레임 버퍼 는 메모리 의 한 구역 으로 읽 기, 쓰기, 매 핑 이 가능 합 니 다.초기 화 단계 에서 디 스 플레이 장 치 를 사용자 프로 세 스 공간 에 표시 하면 화면의 모든 점 과 프레임 버퍼 의 모든 점 을 일일이 대응 하 는 것 으로 이해 할 수 있 습 니 다.이렇게 하면 이 메모리 영역 에 정 의 된 픽 셀 과 색상 을 채 울 수 있 고 화면 도 방금 기 록 된 픽 셀 과 색상 에 따라 다채로운 화면 을 나 타 낼 수 있 습 니 다.
3 2.6.25 커 널 Frambuffer 와 관련 된 데이터 구조
관련 데이터 구 조 는 운영 환경 에서 사용자 공간 과 커 널 공간 두 가지 로 나 눌 수 있다.사용자 공간 에서 사용 하 는 데이터 구 조 는 주로 fbfix_screenfo 와 fbvar_screeninfo。커 널 공간 에서 사용 하 는 주요 데이터 구 조 는 fb 입 니 다.info。
먼저 fb 소개fix_screenfo, 이 데이터 구 조 는 시스템 이 실행 되 는 동안 변경 할 수 없 는 정 보 를 정의 합 니 다. 예 를 들 어 장치 이름, 화면의 픽 셀 수량, 버퍼 의 첫 주소 와 길이 등 입 니 다.이런 정 보 는 일반적으로 ioctl 함 수 를 통 해 얻 을 수 있다.다음은 fbfix_screenfo 의 주요 내용:
C/C++ code
struct
fb_fix_screeninfo {
char
id[
16
];
/*
*/
unsigned
long
smem_start;
/*
frame buffer ( )
*/
__u32 smem_len;
/*
*/
__u32 type;
/*
, TFT STN
*/
……
__u32 visual;
/*
, 、
*/
……
__u32 line_length;
/*
*/
unsigned
long
mmio_start;
/*
IO ( )
*/
__u32 mmio_len;
/*
IO
*/
__u32 accel;
/*
*/
__u16 reserved[
3
];
/*
*/
};
相对应的,fb_var_screeninfo定义了一些在系统运行期间可以改变的信息。例如像素深度、灰度级、颜色格式、时序,屏幕边缘空白区等。下表中列出了fb_var_screeninfo的主要内容:
- C/C++ code
-
struct fb_var_screeninfo {__u32 xres; /* visible resolution */__u32 yres;__u32 xres_virtual; /* virtual resolution */__u32 yres_virtual;__u32 xoffset; /* */__u32 yoffset;__u32 bits_per_pixel; /* */__u32 grayscale; /* */struct fb_bitfield red;struct fb_bitfield green;struct fb_bitfield blue;struct fb_bitfield transp; /* */__u32 nonstd; /* */……__u32 pixclock; /* , */__u32 left_margin; /* */__u32 right_margin; /* */__u32 upper_margin; /* */__u32 lower_margin;__u32 hsync_len; /* */__u32 vsync_len; /* */ ……. };
아래 아이콘 은 화면 전체 에 있 는 여러 가장자리 구역 의 위 치 를 표시 합 니 다.
커 널 레벨 Fbinfo
C/C++ codestruct fb_info { int node; /* */ int flags; struct fb_var_screeninfo var; /* */ struct fb_fix_screeninfo fix; /* */ struct fb_monspecs monspecs; /* */ struct work_struct queue; /* */ struct fb_pixmap pixmap; /* */ struct fb_pixmap sprite; /* */ struct fb_cmap cmap; /* */ struct list_head modelist; /* */ struct fb_videomode * mode; /* */ ...... struct fb_ops * fbops; /* */ …… struct device * dev; /* */ …… char __iomem * screen_base; /* IO ( ) */ unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ void * pseudo_palette; /* */ …… };
fb_info 는 디 스 플레이 구동 작업 의 주요 캐리어 로 현재 디 스 플레이 구동 과 콘 솔 에 관 한 모든 정 보 를 정의 합 니 다.디 스 플레이 구동 의 실현 형식 은 fb 를 초기 화 하 는 것 입 니 다.info 각 항목, LCD 컨트롤 러 설정 에 사용.이후 대부분의 작업 은 응용 층 이 ioctl 시스템 을 통 해 fb 를 호출 하 는 것 입 니 다.ops 의 함 수 는 fix, var 변수 중 값 을 얻 거나 수정 하여 레지스터 에 기록 합 니 다.팔레트 수정 등 작업.응용 층 에 표시 할 두 프레임 의 그림 에 사용 할 팔레트 가 다 르 면 fbops 의 함수 가 실현 되 고 후 자 는 팔레트 가 메모리 에 있 는 주 소 를 얻 으 며 그 중의 픽 셀 값 을 수정 하여 이 루어 집 니 다.
Fb_ops 안에 함수 포인터 가 많 습 니 다. 이런 함수 포인터 가 가리 키 는 것 은 보통 각 하드웨어 그래 픽 카드 가 자체 적 으로 가지 고 있 는 바 텀 구동 함수 입 니 다. 만약 에 독자 가 전문 적 인 그래 픽 카드 를 개발 하려 면 fbops 이 구조 에 서 는 반드시 포인터 로 이런 그래 픽 카드 전용 함수 들 을 열거 해 야 한다.우 리 는 그 중의 두 함수 지침 만 간단하게 소개 합 니 다.
C/C++ codeint ( * fb_check_var)( struct fb_var_screeninfo * var, struct fb_info * info);
이 포인터 가 가리 키 는 함 수 는 앞에서 언급 한 가 변 디 스 플레이 파 라 메 터 를 검사 하 는 데 사 용 됩 니 다. 예 를 들 어 픽 셀 깊이, 가장자리 너비 또는 깊이 등 입 니 다.여기 있 는 인 자 는 수정 되 지 않 습 니 다.
C/C++ codeint ( * fb_set_par)( struct fb_info * info);
여기 서 가리 키 는 함 수 는 표시 매개 변 수 를 실질 적 으로 수정 할 수 있 습 니 다.4 Frambuffer 구동 실현 프레임 워 크 여기 서 우 리 는 모두 가 이미 비교적 익숙 한 드라이버 등록 과 취소 두 과정 을 반복 하지 않 는 다.우 리 는 fbmem. c 의 몇 가지 중요 함 수 를 대상 으로 등록 후 로그아웃 하기 전에 프레임 버퍼 구동 의 대체적인 절 차 를 설명 합 니 다.fbmem. c 의 함 수 를 선택 한 이 유 는 이 파일 의 함수 가 일정한 대표 성 을 가지 기 때 문 입 니 다. 독자 들 은 그들의 대체적인 구 조 를 이해 한 후에 하 나 를 들 어 다른 구체 적 인 그래 픽 카드 의 드라이버 를 분석 하고 이해 할 수 있 습 니 다. 이 몇 개의 함 수 는 각각 fb 이다.mmap,fb_set_var 와 fbioctl。 Fb_mmap 는 말 그대로 장치 에서 시스템 메모리 (가상 주소) 사이 의 맵 을 완성 하 는 것 입 니 다.
C/C++ codestatic int fb_mmap(struct file *file, struct vm_area_struct * vma){int fbidx = iminor(file->f_path.dentry->d_inode); struct fb_info *info = registered_fb[fbidx]; struct fb_ops *fb = info->fbops;unsigned long off;unsigned long start;u32 len;if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))return -EINVAL;off = vma->vm_pgoff << PAGE_SHIFT;if (!fb)return -ENODEV;if (fb->fb_mmap) { // : mmap ,int res;lock_kernel(); //res = fb->fb_mmap(info, vma); // mmapunlock_kernel();return res;} lock_kernel(); start = info->fix.smem_start; // , len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); // if (off >= len) { /* I/O */ off -= len; if (info->var.accel_flags) { unlock_kernel(); return -EINVAL; } start = info->fix.mmio_start;// I/O len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); } unlock_kernel(); start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) // return -EINVAL; off += start; vma->vm_pgoff = off >> PAGE_SHIFT; /* IO , */ vma->vm_flags |= VM_IO | VM_RESERVED; fb_pgprotect(file, vma, off); // , if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) // return -EAGAIN; return 0; }
这里的映射行为发生在驱动程序初始化阶段。请注意,这些行为是否被囊括在一个名
为mmap的函数中并不是问题的关键,我们在开发中真正应该关心的是映射所需要的前提
条件如设备物理地址的提取,映射长度的确认以及实际的映射操作。只要在驱动程序的初
始化中完成了上述动作,那就算是成功了。因此,不少显卡的驱动程序里是找不到mmap
这个函数的,但它们一样工作得很好,原因就是它们已经完成了实际的映射操作。
下面我们看看fb_set_var函数。它主要完成了显示模式、可变参数的设置。
Fb_set_var这样的函数在不同的显示驱动中的具体名称也不一样,但基本上
的功能都是完成对于模式和可变参数的控制。某些系统的驱动里fb_set_var
是不含fb_check_var这样的函数的。
- C/C++ code
-
int fb_set_var( struct fb_info * info, struct fb_var_screeninfo * var) { int flags = info -> flags; int ret = 0 ; ……. if ( ! info -> fbops -> fb_check_var) { * var = info -> var; goto done; } ret = info -> fbops -> fb_check_var(var, info); // if (ret) goto done; if ((var -> activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { struct fb_videomode mode; …… info -> var = * var; if (info -> fbops -> fb_set_par) // fb_set_par info -> fbops -> fb_set_par(info); // fb_pan_display(info, & info -> var); // fb_set_cmap( & info -> cmap, info); // fb_var_to_videomode( & mode, & info -> var); // ...... } } } done: return ret; }
Fb_ioctl 함 수 는 커 널 에서 디 스 플레이 장치 매개 변 수 를 읽 는 것 (가 변 적 이 고 고정 적 인 것 이 모두 있 음) 을 포함 하여 많은 기능 을 모 았 습 니 다. 매개 변 수 를 설정 하 는 것 (위 에서 언급 한 fb set var 함수 호출) 입 니 다.이러한 기능 은 일반적으로 분류 방면 의 제한 이 없 기 때문에 개발 자 는 각종 자신 이 실현 한 기능 을 모두 fb 에 넣 을 수 있다.ioctl 중.그리고 개발 자 들 도 시스템 이 제공 하 는 이 fb 를 완전히 버 릴 수 있다.ioctl 전환 자신의 fbioctl。
C/C++ codestatic int fb_ioctl( struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { int fbidx = iminor(inode); struct fb_info * info = registered_fb[fbidx]; // struct fb_ops * fb = info -> fbops; // struct fb_var_screeninfo var; // struct fb_fix_screeninfo fix; // struct fb_con2fbmap con2fb; struct fb_cmap_user cmap; // struct fb_event event ; void __user * argp = ( void __user * )arg; int i; if ( ! fb) return - ENODEV; switch (cmd) { case FBIOGET_VSCREENINFO: return copy_to_user(argp, & info -> var, sizeof (var)) ? - EFAULT : 0 ; // case FBIOPUT_VSCREENINFO: if (copy_from_user( & var, argp, sizeof (var))) return - EFAULT; // ? acquire_console_sem(); // info -> flags |= FBINFO_MISC_USEREVENT; i = fb_set_var(info, & var); // info -> flags &= ~ FBINFO_MISC_USEREVENT; release_console_sem(); // if (i) return i; if (copy_to_user(argp, & var, sizeof (var))) return - EFAULT; return 0 ; case FBIOGET_FSCREENINFO: return copy_to_user(argp, & info -> fix, // sizeof (fix)) ? - EFAULT : 0 ; case FBIOPUTCMAP: // if (copy_from_user( & cmap, argp, sizeof (cmap))) return - EFAULT; return (fb_set_user_cmap( & cmap, info)); …… case FBIOBLANK: acquire_console_sem(); info -> flags |= FBINFO_MISC_USEREVENT; i = fb_blank(info, arg); // info -> flags &= ~ FBINFO_MISC_USEREVENT; release_console_sem(); return i; default : if (fb -> fb_ioctl == NULL) // fb_ioctl return - EINVAL; return fb -> fb_ioctl(info, cmd, arg); } }
위의 서술 과정 에서 볼 수 있 듯 이 프레임 버퍼 드라이버 에 대해 서로 다른 디 스 플레이 장치 가 서로 다른 특정한 기능 을 가 질 수 있 지만 커 널 에 드라이버 를 등록 한 후에 실행 하 는 공통점 은 모두 물리 장치 와 가상 메모리 간 의 매 핑 (fb mmap) 을 먼저 해 야 한 다 는 것 이다.장 비 를 조작 하 는 과정 에서 fbset_var 는 설비 의 운행 매개 변 수 를 제어 할 수 있 기 때문에 특히 중요 하 다.유사 한 장치 매개 변수 읽 기와 쓰기 함수 그리고 fbcheck_var 등, 이 함수 들 은 일반적으로 fb 에 포 함 됩 니 다.ioctl 함수 에서 호출 되 었 습 니 다.상기 매개 변수의 조작 대상 은 바로 우리 가 지난 절 에 소개 한 fb 이다.info,fb_fix_screeninfo ,fb_var_screenfo 등 데이터 구조.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.