요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======================
The Frame Buffer Device
=======================
Last revised: May 10, 2001
0. Introduction
---------------
The frame buffer device provides an abstraction for the graphics hardware. It
represents the frame buffer of some video hardware and allows application
software to access the graphics hardware through a well-defined interface, so
the software doesn't need to know anything about the low-level (hardware
register) stuff.
The device is accessed through special device nodes, usually located in the
/dev directory, i.e. /dev/fb*.
1. User's View of /dev/fb*
--------------------------
From the user's point of view, the frame buffer device looks just like any
other device in /dev. It's a character device using major 29; the minor
specifies the frame buffer number.
By convention, the following device nodes are used (numbers indicate the device
minor numbers)::
0 = /dev/fb0 First frame buffer
1 = /dev/fb1 Second frame buffer
...
31 = /dev/fb31 32nd frame buffer
For backwards compatibility, you may want to create the following symbolic
links::
/dev/fb0current -> fb0
/dev/fb1current -> fb1
and so on...
The frame buffer devices are also `normal` memory devices, this means, you can
read and write their contents. You can, for example, make a screen snapshot by::
cp /dev/fb0 myfile
There also can be more than one frame buffer at a time, e.g. if you have a
graphics card in addition to the built-in hardware. The corresponding frame
buffer devices (/dev/fb0 and /dev/fb1 etc.) work independently.
Application software that uses the frame buffer device (e.g. the X server) will
use /dev/fb0 by default (older software uses /dev/fb0current). You can specify
an alternative frame buffer device by setting the environment variable
$FRAMEBUFFER to the path name of a frame buffer device, e.g. (for sh/bash
users)::
export FRAMEBUFFER=/dev/fb1
or (for csh users)::
setenv FRAMEBUFFER /dev/fb1
After this the X server will use the second frame buffer.
2. Programmer's View of /dev/fb*
--------------------------------
As you already know, a frame buffer device is a memory device like /dev/mem and
it has the same features. You can read it, write it, seek to some location in
it and mmap() it (the main usage). The difference is just that the memory that
appears in the special file is not the whole memory, but the frame buffer of
some video hardware.
/dev/fb* also allows several ioctls on it, by which lots of information about
the hardware can be queried and set. The color map handling works via ioctls,
too. Look into <linux/fb.h> for more information on what ioctls exist and on
which data structures they work. Here's just a brief overview:
- You can request unchangeable information about the hardware, like name,
organization of the screen memory (planes, packed pixels, ...) and address
and length of the screen memory.
- You can request and change variable information about the hardware, like
visible and virtual geometry, depth, color map format, timing, and so on.
If you try to change that information, the driver maybe will round up some
values to meet the hardware's capabilities (or return EINVAL if that isn't
possible).
- You can get and set parts of the color map. Communication is done with 16
bits per color part (red, green, blue, transparency) to support all
existing hardware. The driver does all the computations needed to apply
it to the hardware (round it down to less bits, maybe throw away
transparency).
All this hardware abstraction makes the implementation of application programs
easier and more portable. E.g. the X server works completely on /dev/fb* and
thus doesn't need to know, for example, how the color registers of the concrete
hardware are organized. XF68_FBDev is a general X server for bitmapped,
unaccelerated video hardware. The only thing that has to be built into
application programs is the screen organization (bitplanes or chunky pixels
etc.), because it works on the frame buffer image data directly.
For the future it is planned that frame buffer drivers for graphics cards and
the like can be implemented as kernel modules that are loaded at runtime. Such
a driver just has to call register_framebuffer() and supply some functions.
Writing and distributing such drivers independently from the kernel will save
much trouble...
3. Frame Buffer Resolution Maintenance
--------------------------------------
Frame buffer resolutions are maintained using the utility `fbset`. It can
change the video mode properties of a frame buffer device. Its main usage is
to change the current video mode, e.g. during boot up in one of your `/etc/rc.*`
or `/etc/init.d/*` files.
Fbset uses a video mode database stored in a configuration file, so you can
easily add your own modes and refer to them with a simple identifier.
4. The X Server
---------------
The X server (XF68_FBDev) is the most notable application program for the frame
buffer device. Starting with XFree86 release 3.2, the X server is part of
XFree86 and has 2 modes:
- If the `Display` subsection for the `fbdev` driver in the /etc/XF86Config
file contains a::
Modes "default"
line, the X server will use the scheme discussed above, i.e. it will start
up in the resolution determined by /dev/fb0 (or $FRAMEBUFFER, if set). You
still have to specify the color depth (using the Depth keyword) and virtual
resolution (using the Virtual keyword) though. This is the default for the
configuration file supplied with XFree86. It's the most simple
configuration, but it has some limitations.
- Therefore it's also possible to specify resolutions in the /etc/XF86Config
file. This allows for on-the-fly resolution switching while retaining the
same virtual desktop size. The frame buffer device that's used is still
/dev/fb0current (or $FRAMEBUFFER), but the available resolutions are
defined by /etc/XF86Config now. The disadvantage is that you have to
specify the timings in a different format (but `fbset -x` may help).
To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't
work 100% with XF68_FBDev: the reported clock values are always incorrect.
5. Video Mode Timings
---------------------
A monitor draws an image on the screen by using an electron beam (3 electron
beams for color models, 1 electron beam for monochrome monitors). The front of
the screen is covered by a pattern of colored phosphors (pixels). If a phosphor
is hit by an electron, it emits a photon and thus becomes visible.
The electron beam draws horizontal lines (scanlines) from left to right, and
from the top to the bottom of the screen. By modifying the intensity of the
electron beam, pixels with various colors and intensities can be shown.
After each scanline the electron beam has to move back to the left side of the
screen and to the next line: this is called the horizontal retrace. After the
whole screen (frame) was painted, the beam moves back to the upper left corner:
this is called the vertical retrace. During both the horizontal and vertical
retrace, the electron beam is turned off (blanked).
The speed at which the electron beam paints the pixels is determined by the
dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
of cycles per second), each pixel is 35242 ps (picoseconds) long::
1/(28.37516E6 Hz) = 35.242E-9 s
If the screen resolution is 640x480, it will take::
640*35.242E-9 s = 22.555E-6 s
to paint the 640 (xres) pixels on one scanline. But the horizontal retrace
also takes time (e.g. 272 `pixels`), so a full scanline takes::
(640+272)*35.242E-9 s = 32.141E-6 s
We'll say that the horizontal scanrate is about 31 kHz::
1/(32.141E-6 s) = 31.113E3 Hz
A full screen counts 480 (yres) lines, but we have to consider the vertical
retrace too (e.g. 49 `lines`). So a full screen will take::
(480+49)*32.141E-6 s = 17.002E-3 s
The vertical scanrate is about 59 Hz::
1/(17.002E-3 s) = 58.815 Hz
This means the screen data is refreshed about 59 times per second. To have a
stable picture without visible flicker, VESA recommends a vertical scanrate of
at least 72 Hz. But the perceived flicker is very human dependent: some people
can use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz.
Since the monitor doesn't know when a new scanline starts, the graphics board
will supply a synchronization pulse (horizontal sync or hsync) for each
scanline. Similarly it supplies a synchronization pulse (vertical sync or
vsync) for each new frame. The position of the image on the screen is
influenced by the moments at which the synchronization pulses occur.
The following picture summarizes all timings. The horizontal retrace time is
the sum of the left margin, the right margin and the hsync length, while the
vertical retrace time is the sum of the upper margin, the lower margin and the
vsync length::
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |upper_margin | | |
| | ↓ | | |
+----------###############################################----------+-------+
| # ↑ # | |
| # | # | |
| # | # | |
| # | # | |
| left # | # right | hsync |
| margin # | xres # margin | len |
|<-------->#<---------------+--------------------------->#<-------->|<----->|
| # | # | |
| # | # | |
| # | # | |
| # |yres # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # ↓ # | |
+----------###############################################----------+-------+
| | ↑ | | |
| | |lower_margin | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |vsync_len | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
The frame buffer device expects all horizontal timings in number of dotclocks
(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
6. Converting XFree86 timing values info frame buffer device timings
--------------------------------------------------------------------
An XFree86 mode line consists of the following fields::
"800x600" 50 800 856 976 1040 600 637 643 666
< name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
The frame buffer device uses the following fields:
- pixclock: pixel clock in ps (pico seconds)
- left_margin: time from sync to picture
- right_margin: time from picture to sync
- upper_margin: time from sync to picture
- lower_margin: time from picture to sync
- hsync_len: length of horizontal sync
- vsync_len: length of vertical sync
1) Pixelclock:
xfree: in MHz
fb: in picoseconds (ps)
pixclock = 1000000 / DCF
2) horizontal timings:
left_margin = HFL - SH2
right_margin = SH1 - HR
hsync_len = SH2 - SH1
3) vertical timings:
upper_margin = VFL - SV2
lower_margin = SV1 - VR
vsync_len = SV2 - SV1
Good examples for VESA timings can be found in the XFree86 source tree,
under "xc/programs/Xserver/hw/xfree86/doc/modeDB.txt".
7. References
-------------
For more specific information about the frame buffer device and its
applications, please refer to the Linux-fbdev website:
http://linux-fbdev.sourceforge.net/
and to the following documentation:
- The manual pages for fbset: fbset(8), fb.modes(5)
- The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)
- The mighty kernel sources:
- linux/drivers/video/
- linux/include/linux/fb.h
- linux/include/video/
8. Mailing list
---------------
There is a frame buffer device related mailing list at kernel.org:
Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
subscription information and archive browsing.
9. Downloading
--------------
All necessary files can be found at
ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/
and on its mirrors.
The latest version of fbset can be found at
http://www.linux-fbdev.org/
10. Credits
-----------
This readme was written by Geert Uytterhoeven, partly based on the original
`X-framebuffer.README` by Roman Hodek and Martin Schaller. Section 6 was
provided by Frank Neumann.
The frame buffer device abstraction was designed by Martin Schaller.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
프레임 버퍼 장치의 목적과 접근 경로
1-20프레임 버퍼 장치는 그래픽 하드웨어를 추상화합니다. 비디오 하드웨어의 프레임 버퍼를 잘 정의된 인터페이스로 노출하므로 응용 프로그램은 저수준 하드웨어 레지스터를 직접 알 필요가 없습니다.
장치는 일반적으로 `/dev` 아래의 `/dev/fb*` 특수 장치 노드로 접근합니다. 문서의 마지막 개정일은 2001년 5월 10일이며, 뒤의 절에서는 사용자 관점과 프로그래머 관점, 화면 모드 타이밍을 차례로 설명합니다.
응용 프로그램과 실제 그래픽 하드웨어 사이에 fbdev 인터페이스가 놓입니다.
=======================
The Frame Buffer Device
=======================
Last revised: May 10, 2001
0. Introduction
---------------
The frame buffer device provides an abstraction for the graphics hardware. It
represents the frame buffer of some video hardware and allows application
software to access the graphics hardware through a well-defined interface, so
the software doesn't need to know anything about the low-level (hardware
register) stuff.
The device is accessed through special device nodes, usually located in the
/dev directory, i.e. /dev/fb*.
사용자 관점의 `/dev/fb*`
21-67사용자에게 프레임 버퍼는 `/dev`의 다른 문자 장치와 비슷하게 보입니다. 주 장치 번호는 29이고 부 장치 번호가 프레임 버퍼 번호를 나타냅니다. 관례상 부 번호 0은 `/dev/fb0`, 1은 `/dev/fb1`, 31은 `/dev/fb31`에 대응합니다.
이전 소프트웨어와의 호환성을 위해 `/dev/fb0current -> fb0`, `/dev/fb1current -> fb1` 같은 심볼릭 링크를 만들 수 있습니다. 프레임 버퍼는 일반 메모리 장치처럼 읽고 쓸 수 있으므로 `cp /dev/fb0 myfile`로 화면 내용을 파일에 복사할 수도 있습니다.
내장 그래픽과 별도 그래픽 카드처럼 프레임 버퍼가 여러 개 존재할 수 있으며 `/dev/fb0`, `/dev/fb1` 등은 서로 독립적으로 동작합니다. X 서버 같은 프로그램은 기본적으로 `/dev/fb0`을 사용하고 오래된 프로그램은 `/dev/fb0current`를 사용합니다.
다른 장치를 선택하려면 `$FRAMEBUFFER` 환경 변수에 장치 경로를 지정합니다. sh 또는 bash에서는 `export FRAMEBUFFER=/dev/fb1`, csh에서는 `setenv FRAMEBUFFER /dev/fb1`을 사용하며, 이후 X 서버는 두 번째 프레임 버퍼를 사용합니다.
1. User's View of /dev/fb*
--------------------------
From the user's point of view, the frame buffer device looks just like any
other device in /dev. It's a character device using major 29; the minor
specifies the frame buffer number.
By convention, the following device nodes are used (numbers indicate the device
minor numbers)::
0 = /dev/fb0 First frame buffer
1 = /dev/fb1 Second frame buffer
...
31 = /dev/fb31 32nd frame buffer
For backwards compatibility, you may want to create the following symbolic
links::
/dev/fb0current -> fb0
/dev/fb1current -> fb1
and so on...
The frame buffer devices are also `normal` memory devices, this means, you can
read and write their contents. You can, for example, make a screen snapshot by::
cp /dev/fb0 myfile
There also can be more than one frame buffer at a time, e.g. if you have a
graphics card in addition to the built-in hardware. The corresponding frame
buffer devices (/dev/fb0 and /dev/fb1 etc.) work independently.
Application software that uses the frame buffer device (e.g. the X server) will
use /dev/fb0 by default (older software uses /dev/fb0current). You can specify
an alternative frame buffer device by setting the environment variable
$FRAMEBUFFER to the path name of a frame buffer device, e.g. (for sh/bash
users)::
export FRAMEBUFFER=/dev/fb1
or (for csh users)::
setenv FRAMEBUFFER /dev/fb1
After this the X server will use the second frame buffer.
프로그래머 관점과 ioctl 추상화
68-112프로그래머 관점에서 프레임 버퍼는 `/dev/mem`과 비슷한 메모리 장치입니다. 읽기, 쓰기, seek와 `mmap()`을 지원하며, 주된 사용 방식은 `mmap()`으로 비디오 메모리를 주소 공간에 매핑하는 것입니다. 차이는 전체 물리 메모리가 아니라 특정 비디오 하드웨어의 프레임 버퍼만 보인다는 점입니다.
`/dev/fb*`에는 하드웨어 정보를 조회하고 설정하는 여러 ioctl이 있습니다. 사용 가능한 ioctl과 데이터 구조는 `<linux/fb.h>`에 정의됩니다. 변경할 수 없는 정보에는 이름, plane 또는 packed pixel 같은 화면 메모리 구성, 화면 메모리 주소와 길이가 포함됩니다.
가시 및 가상 해상도, 색 깊이, 컬러 맵 형식과 타이밍 같은 가변 정보도 조회하고 변경할 수 있습니다. 드라이버는 하드웨어 제약에 맞게 값을 반올림할 수 있고, 수용할 수 없는 요청에는 `EINVAL`을 반환합니다.
컬러 맵은 빨강, 초록, 파랑, 투명도 각 성분을 16비트로 교환합니다. 드라이버는 실제 하드웨어 비트 수에 맞게 줄이고 필요하면 투명도를 버리는 변환을 수행합니다.
이 추상화 덕분에 응용 프로그램의 구현과 이식성이 좋아집니다. `XF68_FBDev` X 서버는 비트맵 기반 비가속 하드웨어에서 `/dev/fb*`만 사용하므로 실제 색상 레지스터 배치를 알 필요가 없습니다. 다만 응용 프로그램이 영상 데이터 자체를 다루므로 bitplane인지 chunky pixel인지 같은 화면 구성은 알아야 합니다.
향후 그래픽 카드용 프레임 버퍼 드라이버를 실행 중에 적재하는 커널 모듈로 만들 계획도 설명합니다. 이런 드라이버는 `register_framebuffer()`를 호출하고 필요한 함수를 제공하면 되므로 커널과 독립적으로 작성하고 배포할 수 있습니다.
2. Programmer's View of /dev/fb*
--------------------------------
As you already know, a frame buffer device is a memory device like /dev/mem and
it has the same features. You can read it, write it, seek to some location in
it and mmap() it (the main usage). The difference is just that the memory that
appears in the special file is not the whole memory, but the frame buffer of
some video hardware.
/dev/fb* also allows several ioctls on it, by which lots of information about
the hardware can be queried and set. The color map handling works via ioctls,
too. Look into <linux/fb.h> for more information on what ioctls exist and on
which data structures they work. Here's just a brief overview:
- You can request unchangeable information about the hardware, like name,
organization of the screen memory (planes, packed pixels, ...) and address
and length of the screen memory.
- You can request and change variable information about the hardware, like
visible and virtual geometry, depth, color map format, timing, and so on.
If you try to change that information, the driver maybe will round up some
values to meet the hardware's capabilities (or return EINVAL if that isn't
possible).
- You can get and set parts of the color map. Communication is done with 16
bits per color part (red, green, blue, transparency) to support all
existing hardware. The driver does all the computations needed to apply
it to the hardware (round it down to less bits, maybe throw away
transparency).
All this hardware abstraction makes the implementation of application programs
easier and more portable. E.g. the X server works completely on /dev/fb* and
thus doesn't need to know, for example, how the color registers of the concrete
hardware are organized. XF68_FBDev is a general X server for bitmapped,
unaccelerated video hardware. The only thing that has to be built into
application programs is the screen organization (bitplanes or chunky pixels
etc.), because it works on the frame buffer image data directly.
For the future it is planned that frame buffer drivers for graphics cards and
the like can be implemented as kernel modules that are loaded at runtime. Such
a driver just has to call register_framebuffer() and supply some functions.
Writing and distributing such drivers independently from the kernel will save
much trouble...
`fbset`과 X 서버의 화면 모드
113-154프레임 버퍼 해상도는 `fbset` 유틸리티로 관리합니다. 이 도구는 프레임 버퍼 장치의 비디오 모드 속성을 바꾸며, 부팅 중 `/etc/rc.*` 또는 `/etc/init.d/*` 스크립트에서 현재 모드를 설정하는 데 주로 사용됩니다. 모드 데이터베이스를 설정 파일에 저장하므로 사용자 모드를 이름으로 추가하고 선택할 수 있습니다.
`XF68_FBDev`는 XFree86 3.2부터 XFree86에 포함되며 두 가지 방식으로 동작합니다. `/etc/XF86Config`의 `fbdev` 드라이버 `Display` 하위 절에 `Modes "default"`가 있으면 `/dev/fb0` 또는 `$FRAMEBUFFER`가 가리키는 현재 해상도로 시작합니다. 이때도 `Depth`와 `Virtual`은 지정해야 합니다.
두 번째 방식은 `/etc/XF86Config`에 해상도와 타이밍을 직접 정의합니다. 같은 가상 데스크톱 크기를 유지한 채 즉시 해상도를 전환할 수 있지만 fbdev와 다른 형식으로 타이밍을 적어야 하며 `fbset -x`가 변환을 도울 수 있습니다. 이 방식이 사용하는 장치는 문서 당시의 `/dev/fb0current` 또는 `$FRAMEBUFFER`입니다.
비디오 모드 조정에는 `fbset` 또는 `xvidtune`을 사용할 수 있습니다. 단, `xvidtune`은 `XF68_FBDev`와 완전히 호환되지 않아 표시하는 clock 값이 항상 부정확합니다.
3. Frame Buffer Resolution Maintenance
--------------------------------------
Frame buffer resolutions are maintained using the utility `fbset`. It can
change the video mode properties of a frame buffer device. Its main usage is
to change the current video mode, e.g. during boot up in one of your `/etc/rc.*`
or `/etc/init.d/*` files.
Fbset uses a video mode database stored in a configuration file, so you can
easily add your own modes and refer to them with a simple identifier.
4. The X Server
---------------
The X server (XF68_FBDev) is the most notable application program for the frame
buffer device. Starting with XFree86 release 3.2, the X server is part of
XFree86 and has 2 modes:
- If the `Display` subsection for the `fbdev` driver in the /etc/XF86Config
file contains a::
Modes "default"
line, the X server will use the scheme discussed above, i.e. it will start
up in the resolution determined by /dev/fb0 (or $FRAMEBUFFER, if set). You
still have to specify the color depth (using the Depth keyword) and virtual
resolution (using the Virtual keyword) though. This is the default for the
configuration file supplied with XFree86. It's the most simple
configuration, but it has some limitations.
- Therefore it's also possible to specify resolutions in the /etc/XF86Config
file. This allows for on-the-fly resolution switching while retaining the
same virtual desktop size. The frame buffer device that's used is still
/dev/fb0current (or $FRAMEBUFFER), but the available resolutions are
defined by /etc/XF86Config now. The disadvantage is that you have to
specify the timings in a different format (but `fbset -x` may help).
To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't
work 100% with XF68_FBDev: the reported clock values are always incorrect.
주사, 귀선과 동기 타이밍
155-255CRT 모니터는 전자빔으로 화면의 형광체를 자극해 영상을 그립니다. 전자빔은 왼쪽에서 오른쪽으로 scanline을 그리고 위에서 아래로 이동합니다. 각 scanline 뒤에는 왼쪽과 다음 줄로 돌아가는 horizontal retrace가 있고, 한 frame을 마친 뒤에는 왼쪽 위로 돌아가는 vertical retrace가 있습니다. 두 retrace 동안 전자빔은 꺼져 blank 상태가 됩니다.
픽셀을 그리는 속도는 그래픽 보드의 `dotclock`으로 정합니다. 예를 들어 `28.37516 MHz`에서는 픽셀 하나가 `35242 ps`이며 계산은 `1/(28.37516E6 Hz) = 35.242E-9 s`입니다. 640픽셀을 그리는 시간은 `22.555E-6 s`이고, 수평 귀선 272픽셀을 더한 전체 scanline은 `32.141E-6 s`입니다.
따라서 수평 주사율은 `1/(32.141E-6 s) = 31.113E3 Hz`, 약 31 kHz입니다. 480개의 가시 행에 수직 귀선 49행을 더하면 한 frame은 `17.002E-3 s`, 수직 주사율은 `58.815 Hz`입니다. 화면은 초당 약 59번 갱신됩니다.
문서는 깜박임 없는 안정적인 화면을 위해 VESA가 최소 72 Hz의 수직 주사율을 권장한다고 설명합니다. 다만 깜박임 인지는 개인차가 커서 50 Hz도 편안한 사람이 있는 반면 80 Hz 미만을 알아차리는 사람도 있습니다.
모니터는 새 scanline과 frame의 시작을 스스로 알 수 없으므로 그래픽 보드는 각각 `hsync`와 `vsync` 동기 펄스를 보냅니다. 펄스가 발생하는 시점은 화면에서 영상의 위치에 영향을 줍니다.
수평 귀선 시간은 `left_margin + right_margin + hsync_len`, 수직 귀선 시간은 `upper_margin + lower_margin + vsync_len`입니다. 가시 영역은 `xres`와 `yres`이며, 원문의 큰 ASCII 그림을 아래 표로 같은 구조가 드러나도록 다시 구성했습니다.
프레임 버퍼 장치는 수평 타이밍을 dotclock 수와 picosecond 단위로, 수직 타이밍을 scanline 수로 받습니다.
5. Video Mode Timings
---------------------
A monitor draws an image on the screen by using an electron beam (3 electron
beams for color models, 1 electron beam for monochrome monitors). The front of
the screen is covered by a pattern of colored phosphors (pixels). If a phosphor
is hit by an electron, it emits a photon and thus becomes visible.
The electron beam draws horizontal lines (scanlines) from left to right, and
from the top to the bottom of the screen. By modifying the intensity of the
electron beam, pixels with various colors and intensities can be shown.
After each scanline the electron beam has to move back to the left side of the
screen and to the next line: this is called the horizontal retrace. After the
whole screen (frame) was painted, the beam moves back to the upper left corner:
this is called the vertical retrace. During both the horizontal and vertical
retrace, the electron beam is turned off (blanked).
The speed at which the electron beam paints the pixels is determined by the
dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
of cycles per second), each pixel is 35242 ps (picoseconds) long::
1/(28.37516E6 Hz) = 35.242E-9 s
If the screen resolution is 640x480, it will take::
640*35.242E-9 s = 22.555E-6 s
to paint the 640 (xres) pixels on one scanline. But the horizontal retrace
also takes time (e.g. 272 `pixels`), so a full scanline takes::
(640+272)*35.242E-9 s = 32.141E-6 s
We'll say that the horizontal scanrate is about 31 kHz::
1/(32.141E-6 s) = 31.113E3 Hz
A full screen counts 480 (yres) lines, but we have to consider the vertical
retrace too (e.g. 49 `lines`). So a full screen will take::
(480+49)*32.141E-6 s = 17.002E-3 s
The vertical scanrate is about 59 Hz::
1/(17.002E-3 s) = 58.815 Hz
This means the screen data is refreshed about 59 times per second. To have a
stable picture without visible flicker, VESA recommends a vertical scanrate of
at least 72 Hz. But the perceived flicker is very human dependent: some people
can use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz.
Since the monitor doesn't know when a new scanline starts, the graphics board
will supply a synchronization pulse (horizontal sync or hsync) for each
scanline. Similarly it supplies a synchronization pulse (vertical sync or
vsync) for each new frame. The position of the image on the screen is
influenced by the moments at which the synchronization pulses occur.
The following picture summarizes all timings. The horizontal retrace time is
the sum of the left margin, the right margin and the hsync length, while the
vertical retrace time is the sum of the upper margin, the lower margin and the
vsync length::
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |upper_margin | | |
| | ↓ | | |
+----------###############################################----------+-------+
| # ↑ # | |
| # | # | |
| # | # | |
| # | # | |
| left # | # right | hsync |
| margin # | xres # margin | len |
|<-------->#<---------------+--------------------------->#<-------->|<----->|
| # | # | |
| # | # | |
| # | # | |
| # |yres # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # ↓ # | |
+----------###############################################----------+-------+
| | ↑ | | |
| | |lower_margin | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |vsync_len | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
The frame buffer device expects all horizontal timings in number of dotclocks
(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
XFree86 Modeline을 fbdev 타이밍으로 변환
256-300XFree86 mode line 예시는 `"800x600" 50 800 856 976 1040 600 637 643 666`입니다. 필드는 차례로 `name`, `DCF`, `HR`, `SH1`, `SH2`, `HFL`, `VR`, `SV1`, `SV2`, `VFL`을 뜻합니다.
프레임 버퍼 장치는 `pixclock`, `left_margin`, `right_margin`, `upper_margin`, `lower_margin`, `hsync_len`, `vsync_len` 필드를 사용합니다. `pixclock`은 picosecond 단위의 픽셀 클럭이고 각 margin은 영상과 sync 사이의 시간, sync length는 동기 펄스의 길이입니다.
픽셀 클럭 변환은 `pixclock = 1000000 / DCF`입니다. 수평 값은 `left_margin = HFL - SH2`, `right_margin = SH1 - HR`, `hsync_len = SH2 - SH1`로 구합니다.
수직 값은 `upper_margin = VFL - SV2`, `lower_margin = SV1 - VR`, `vsync_len = SV2 - SV1`로 구합니다. 좋은 VESA 타이밍 예시는 XFree86 소스 트리의 `xc/programs/Xserver/hw/xfree86/doc/modeDB.txt`에서 찾을 수 있습니다.
6. Converting XFree86 timing values info frame buffer device timings
--------------------------------------------------------------------
An XFree86 mode line consists of the following fields::
"800x600" 50 800 856 976 1040 600 637 643 666
< name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
The frame buffer device uses the following fields:
- pixclock: pixel clock in ps (pico seconds)
- left_margin: time from sync to picture
- right_margin: time from picture to sync
- upper_margin: time from sync to picture
- lower_margin: time from picture to sync
- hsync_len: length of horizontal sync
- vsync_len: length of vertical sync
1) Pixelclock:
xfree: in MHz
fb: in picoseconds (ps)
pixclock = 1000000 / DCF
2) horizontal timings:
left_margin = HFL - SH2
right_margin = SH1 - HR
hsync_len = SH2 - SH1
3) vertical timings:
upper_margin = VFL - SV2
lower_margin = SV1 - VR
vsync_len = SV2 - SV1
Good examples for VESA timings can be found in the XFree86 source tree,
under "xc/programs/Xserver/hw/xfree86/doc/modeDB.txt".
참고 자료, 메일링 리스트와 다운로드
301-345더 구체적인 정보와 응용 사례는 문서 당시의 Linux-fbdev 웹사이트 `http://linux-fbdev.sourceforge.net/`을 참조합니다. 관련 매뉴얼 페이지는 `fbset(8)`, `fb.modes(5)`, `XF68_FBDev(1)`, `XF86Config(4/5)`입니다.
커널 소스에서는 `linux/drivers/video/`, `linux/include/linux/fb.h`, `linux/include/video/`가 주요 참고 경로입니다. 현재 트리에서는 파일 배치가 달라질 수 있지만 원문 경로는 역사적 좌표로 그대로 보존합니다.
프레임 버퍼 관련 메일링 리스트 주소는 `[email protected]`이며, 원문은 `http://sourceforge.net/projects/linux-fbdev/`에서 구독 정보와 보관 자료를 보도록 안내합니다.
필요한 파일은 `ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/`와 그 mirror에서 받을 수 있다고 설명합니다. 당시 최신 `fbset`은 `http://www.linux-fbdev.org/`에서 제공했습니다. 이 URL들은 원문 보존을 위해 그대로 옮긴 역사적 링크입니다.
7. References
-------------
For more specific information about the frame buffer device and its
applications, please refer to the Linux-fbdev website:
http://linux-fbdev.sourceforge.net/
and to the following documentation:
- The manual pages for fbset: fbset(8), fb.modes(5)
- The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)
- The mighty kernel sources:
- linux/drivers/video/
- linux/include/linux/fb.h
- linux/include/video/
8. Mailing list
---------------
There is a frame buffer device related mailing list at kernel.org:
[email protected].
Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
subscription information and archive browsing.
9. Downloading
--------------
All necessary files can be found at
ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/
and on its mirrors.
The latest version of fbset can be found at
http://www.linux-fbdev.org/
문서와 설계 기여자
346-353이 README는 Geert Uytterhoeven이 작성했으며 Roman Hodek와 Martin Schaller의 원본 `X-framebuffer.README`를 일부 바탕으로 했습니다. 6절의 XFree86 타이밍 변환은 Frank Neumann이 제공했습니다.
프레임 버퍼 장치 추상화는 Martin Schaller가 설계했습니다.
10. Credits
-----------
This readme was written by Geert Uytterhoeven, partly based on the original
`X-framebuffer.README` by Roman Hodek and Martin Schaller. Section 6 was
provided by Frank Neumann.
The frame buffer device abstraction was designed by Martin Schaller.
요약·해설
framebuffer.rst:1-353이 문서는 Linux 프레임 버퍼 장치를 사용자와 프로그래머 관점에서 설명하고, `/dev/fb*`, ioctl, `mmap()`, `fbset`, XFree86 모드와 CRT 주사 타이밍을 하나의 흐름으로 연결합니다.
핵심은 하드웨어 레지스터를 직접 다루는 대신 fbdev의 고정·가변 정보와 메모리 인터페이스를 사용하는 것입니다. 화면 모드를 옮길 때는 Modeline의 경계값을 margin과 sync 길이로 변환해야 합니다.
장치 선택에서 화면 타이밍 변환까지의 전체 경로입니다.