HOWTO Design your own Framebuffer Splash

本文来自Gentoo Linux Wiki,介绍如何设计自定义帧缓冲启动画面。包括启动画面的初步制作,如创建主题目录和艺术品、主题.cfg文件,编辑GRUB并安装测试;还涉及详细的图形绘制,如绘制盒子、定义进度条、绘制矩形等,最后鼓励读者设计自己的主题。

HOWTO Design your own Framebuffer Splash

From Gentoo Linux Wiki


This article is part of the HOWTO series.
Installation Methods LiveCDs Kernel & Hardware Portage System-related
Networks & Services X Server Software Gaming Other


Table of contents [showhide]
[ edit]

Introduction

This article is not about installing the framebuffer splash, or about configuring your kernel for framebuffer splash - there's plenty of documentation on that already, so get the emergence theme up & running before you try making your own themes. I'm assuming you've got that far before you proceed with designing your own layout.

I wrote this because I wanted to create my own theme, and although I found plenty of themes on the net (mostly for bootsplash used in older kernels) I couldn't find much documented about how to make my own - about the best I could find was "to have an idea how they should look like, have a look at the config files for the default theme". Well, that's what I did.

I don't plan on maintaining this article, so I'd be indebted if you would. Please correct errors & ommissions, but do so accurately - if this works for you, add the article to your watch list so that you can correct other Wikipaedians' spelling & grammer.

[ edit]

Starting out with a splash

Once you know your kernel & grub.conf work with splashutils, it's time to start making your own theme. I wanted to build one with my company logo on it, so unfortunately I can't post the trademarked graphics here - for this demo I'm going to use these (http://img45.exs.cx/img45/7186/silent1280x10247et.jpg) images (http://img18.exs.cx/img18/6623/bootsplash1280x10247vc.jpg) that _mikec_ (http://forums.gentoo.org/profile.php?mode=viewprofile&u=56632) on the forums was having some problems with. This picture isn't quite to my taste, but I hope Mike will forgive me for taking the mickey out of his design.

Try to create your image at high resolution, and only downsize as infrequently as possible. I had some problems with a jpeg created in Photoshop on my Mac, but I found that it worked perfectly when I shipped it over to the target machine as a bitmap & then converted it to jpeg using imagemagick. I couldn't get PNG images to work at all, but maybe I didn't test thoroughly - I later found that sometimes during the boot process (about one time in five) my kernel would hang just before loading the splashscreen but that I'd get no problem on a reboot. This is probably because of the slightly esoteric hardware I'm trying this on, but it may help you - if your kernel hangs on bootup, try a power-cycle.

[ edit]

Make all changes incrementally

When you're making changes to your .cfg files, make all changes incrementally - this means no fancy stuff initially, just add one component at a time & see if that works. If you start from scratch with a massive long .cfg file full of eye-candy and it doesn't work, how do you debug it?

[ edit]

Create a theme directory & artwork

I'm only working on one canvas-size to start with - this machine won't do a framebuffer larger than 1024x768, but you also don't want to be messing around with several sizes at once - get one working and then you can upscale the rest.

When you design your artwork, remember that the verbose screen will need to be mostly dark - the console text is a light grey which works great on black, but not so well on lighter colours. Is there any way to change that, short of modifying the kernel source?


Code: Create a theme directory & artwork
# mkdir -p /etc/splash/mytheme/images
# cp ~/*1024x768.jpg /etc/splash/mytheme/images
# ls /etc/splash/mytheme/images
silent-1024x768.jpg verbose-1024x768.jpg


[ edit]

Create a theme .cfg file

Again, we're gonna keep this absolutely as simple as possible, and cut out all the cruft. We'll still have the original theme to refer back to, but don't worry right now about semi-transparent progress bars - let's just get it working. Just edit /etc/splash/mytheme/1024x768.cfg

File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=25
ty=28
tw=979
th=728

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg


I think the above is about as simple as it gets - if you find that any of these entries are unnecessary, please remove them from this page.

What the above says is:

  • Set background colour to 0, IE no colour, black
  • Set text frame:
    • 25 pixels in from the left
    • 28 pixels down from the top
    • 979 pixels wide
    • 728 pixels deep
  • Paths to
    • verbose background image
    • silent background image

Note:You can find more options in /usr/share/doc/splashutils-*/theme_format.gz - I urge you to read this file and to keep it open for reference.

[ edit]

Edit GRUB

I'm using a fairly unusual RAID array here, so your root= sections will almost certainly be something different - probably something like root=/dev/hda3, I guess.


File: /boot/grub/grub.conf
timeout 15
default 1
fallback 0

title Gentoo Linux - safe?
root (hd0,0)
kernel /bzImage.old root=/dev/discs/disc0/part4

title Gentoo Linux - with my theme!
root (hd0,0)
kernel /bzImage root=/dev/discs/disc0/part4 video=vesafb:ywrap,mtrr,1024x768-16@70 splash=silent,theme:mytheme
initrd /boot/fbsplash-mytheme-1024x768


Note that for the purposes of constructing the splash theme I'm always placing the initrd as a separate file in /boot, rather than compiling it into the kernel. Sure we can compile it into the kernel if we want to when we've finished laying it out, but at the moment that just takes a few extra commands which slow us up - we're gonna need to reboot quite a few times to get everything just how we want it.

[ edit]

Install the theme to /boot & test

You'll find you're running the below commands quite frequently as you tweak the dimensions of your layout - I keep the two lines below close at hand in my history buffer:


Code: Install the theme to /boot & reboot to test
# mount /boot ; splash_geninitramfs -v -g /boot/fbsplash-mytheme-1024x768 -r 1024x768 \
mytheme && umount /boot
# reboot && exit


Freaking ugly, isn't it? Looks to me like Mike is a programmer rather than a graphics designer - sorry, Mike! Don't give up the day job just yet! But if I've got the instructions above right, and you've followed them correctly, then it'll be booting up fine & displaying this picture of a bird with a fat arse & a car appropriate for us Gentoo ricers (http://funroll-loops.org/).

If you just want to test the theme, edit /etc/conf.d/splash and go to vc1 (ctrl+alt+f2) and play around with the commands below:


File: /etc/conf.d/splash
# allows to set different themes on different consoles
# format: "<console>:<theme> <console>:<theme> (...)"
SPLASH_TTY_MAP="1:mytheme"


Code: Test verbose mode
# /etc/init.d/splash restart


Code: Test silent mode
# splash_util --vc=1 -m s -t mytheme -c setcfg
# splash_util --vc=1 -m s -t mytheme -c setpic
# splash_util --vc=1 -m s -t mytheme -c on
# splash_util --vc=1 -m s -p 45000 -t mytheme -c paint


[ edit]

Getting the verbose text right

Ok... so now we've rebooted we can see the picture both in silent & verbose mode.

It's worth mentioning at this point that Mike probably didn't need to do the green Matrixesque tinting in his image program - splashutils offers improvements over the old bootsplash and does transparency & stuff. I think they probably do alpha-blending, too, except I'm not quite sure what that is.

The first thing to do is get the text fitting into the appropriate area in verbose mode. We do this using the tx=, ty=, tw= & th= settings.

It's interesting to note that these are the only commands in the theme format that don't define the box in terms of the x & y co-ordinates of its top-left & bottom-right corners. The verbose text box is defined by the x & y of it's top-left corner and by its width and height.

You can look in /usr/share/doc/splashutils-*/theme_format.gz for more details but the important thing to remember is that if your screen is 1024 pixels wide and you want the verbose text to be 15 pixels in from the left, but 20 pixels in from the right then tx=15 and tw=... erm... 1024 - (15 + 20)... erm... tw=989.

The first time I tried this I just copied & pasted the figures from Mike's posting (http://forums.gentoo.org/viewtopic-p-2203857-highlight-.html#2203857) on the Gentoo forums, and the verbose screen didn't display. These were Mike's settings:

tx=162 
ty=110
tw=955
th=804

Now, I'm not sure if they worked for him, because the original image he sent me was 1280x1024, but these figures won't work on my 1024x768 screen - the sum of tx and tw are more than 1024, and the y & height are more than 768.
Troubleshooting: if your system boots to a login prompt but instead of your verbose screen being displayed you just get a black framebuffer with white writing, check & ensure your height, width and starting co-ordinates are sane relative to the screensize.


File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg


Install the theme, reboot & test! I'd like to say that this looked alright to me, but I didn't like to examine Mike's artwork too closely. Suffice to say it boots & the text came up & stuff.

[ edit]

Displaying a silent message

When the system boots in silent mode, we'd like to display some text saying "Hit f2 to show a bunch of Lunix stuff", just like all the other themes do.

The content of the text is defined in /etc/conf.d/splash, but the text size & colour is part of our theme. Let's edit our config:


File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

text_x=204
text_y=544
text_size=26
text_color=0xffffff

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg

The only change I've made here is the addition of the text_x=, text_y=, text_size= & text_colour= lines.

Respectively these mean:

  • text_x - left-hand edge of text, distance from left of screen.
  • text_y - top edge of text, distance from top of screen.
  • text_size - height of text in pixels.
  • text_color (sic) - colour of the silent text in hex format. 0xffffff means "white"

It's worth observing another unusual case in the layout config here - nowhere else in the theme is the 0x needed before the hex colour code. I believe the 0x is technical for "this is a hex number, not a decimal one", but the colour for the progressbar & other boxes that we'll paint don't need that.

Install the theme, reboot & test!

[ edit]

Understanding hexadecimal colour codes

If you've designed webpages then you may already be familiar with hex colour codes, but here's a quick recap, just in case - you're going to need these throughout your theme.

The principle is that 2563 colours is plenty enough colours to satisfy any interior-decorator, and that hex is a convenient way of describing values between 00 and 255 without wasting any bits. Consequently we define our colour as (I think) RRGGBB, where RR is a value of red between 00 and FF, blended with an amount of green between 00 and FF, and mixed with some blue, too.

Examples:

  • Absolutes:
    • ffffff - white - all of all of the composite colours.
    • 000000 - black - a distinct lack of colour.
  • Greyscales:
    • eeeeee - very light grey - nearly white, in fact.
    • ddddd - light grey
    • 999999 - 60% grey
    • 333333 - 20% grey - quite dark
    • 111111 - very dark - nearly black, in fact.
  • Primaries
    • ff0000 - bright red.
    • 00ff00 - bright green.
    • 0000ff - bright bloo.
  • Composites
    • ffff00 - bright yellow, a mix of red & green
    • ff00ff - bright violet - a mixture of red & blue.

If you want a bunch of useful colours, a Google for "hex colour codes" should bring up a big bunch of useful colour tables (http://www.google.com/search?&q=hex+colour+codes)

[ edit]

Drawing a box

From /usr/share/doc/splashutils-0.9.1/theme_format.gz

box [flags] x0 y0 x1 y1 color1 [color2 color3 color4]
Draws a box on the image.

Flags:

  • silent - The box is drawn only in silent mode. If a box doesn't have this flag set, it's drawn only in verbose mode.
  • noover - This stands for no-overpaint. Boxes with this flag set are painted only when progress == 0 or the repaint command is used.
  • inter - The box will be interpolated with the following one, based on the value of progress.

x0, y0 - coordinates of the upper left corner of the box
x1, y1 - coordinates of the lower right corner of the box

Colors are specified one of the following formats:
#rrggbb or #rrggbbaa.
aa = alpha, 00 - translucent, 255 - solid

If only color1 is specified, the box is filled with the color.

If all four colors are specified, then:

  • color1 is the color of the upper left corner of the box,
  • color2 is the color of the upper right corner of the box,
  • color3 is the color of the lower left corner of the box,
  • color4 is the color of the lower right corner of the box,

and the box if filled with a gradient formed by these colors.



File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

text_x=250
text_y=743
text_size=19
text_color=0xffffff

box silent noover 300 750 824 768 #000000

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg


This box has the attributes:

  • silent - displayed only when the splashscreen is in silent mode.
  • noover - painted the first time the screen is shown and then never updated.
  • Corners:
    • Top left:
      • 300 pixels from the left edge of the screen
      • 750 pixels from the top edge of the screen
    • Bottom right:
      • 824 x 768 - so the box covers approximately the middle third of the screen horizontally, but only the bottom few pixels.
  • Black

If you've scaled the original artwork (http://img45.exs.cx/img45/7186/silent1280x10247et.jpg) to 1024x768 and you're following along, then you'll see why I've drawn this box. Those that are paying attention will see that I've also moved the silent text correspondingly.

Note: this didn't seem to work properly when the text started inside the box, but does so perfectly when the text starts above the top of the box. I have no idea why this might be.

Don't forget to install the theme, reboot & test!

[ edit]

Defining the progressbar

I think the next thing we want to do is get the progressbar working, if nothing for no other reason than to cover that fat bird's hideous arse... erm... I mean to protect the young lady's modesty.

I'm pretty sure there's some requirement about having a baselayout that supports splashutils here - I believe the progressbar is incremented to represent how far the system has proceeded through the active /etc/init.d/ events. I seem to recall reading that splashutils provide an interface for animation events, and so init scripts must call this interface in order to show progress - I presume this is what /etc/conf.d/splash is using to write the text to the splashscreen, too. I'd imagine that all current baselayouts do this correctly, but I don't know for sure - I'm using baselayout-1.11.10.

The critical part of the theme format for the progress bar is where it says "inter - The box will be interpolated with the following one, based on the value of progress". I can't really give a helpful definition of interpolation other than "mixing stuff together" - the best thing to do is look at an example:


File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

text_x=250
text_y=743
text_size=19
text_color=0xffffff

box silent noover 300 750 824 768 #000000

box silent inter 300 350 300 418 #ff00ff
box silent 300 350 824 418 #ff00ff

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg

What these three additional lines basically say is:

  • only in silent mode
    • draw a box
      • only a single pixel wide - from (300,350) to (300,418).
      • interpolate it with the next box, based on progress.
      • make it a suitable colour.
    • draw another box
      • from (300,350) to (824,418).
      • make it the same colour.

So the first "box" is tiny - it's what's used to represent no progress at all, except that we never see the box that small, because it's not painted until the progress begins - I'd guess it's usually 5% or 10% wide when we first see it. The second box represents the completed progress - you'll see it full with when you run shutdown -hf now.

I reckon that, considering splashutils allows transparency, one could have a progress bar that gets darker during the progression. I haven't tried that, so implementation is left as an exercise for the reader.

Install the updated theme, reboot & test!

[ edit]

Drawing rectangles

Ok, so we've got the progressbar working, but it looks kinda lame... something's missing. How does the viewer know where 100% is? Let's draw a rectangle around the progressbar to show how full it is. There are two ways of doing this.

[ edit]

Solid filled


File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

text_x=250
text_y=743
text_size=19
text_color=0xffffff

box silent noover 300 750 824 768 #000000

box silent noover 297 347 827 421 #dcdcdc
box silent inter 300 350 300 418 #ff00ff
box silent 300 350 824 418 #ff00ff

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg

It only takes a single additional line to do this - you can see how it's 3 pixels wider on each side than the progressbar and it's a contrasting colour. The noover option seems a bit of a misnomer to me - it doesn't prevent the box from being overwritten, but rather prevents it from overwriting other graphical items - such as the progressbar on the following two lines. Check it out!

[ edit]

Transparent

Well, that's all well & good, but some folks will want to see what's underneath the progressbar, at least while it's progressing.

Creating a transparent box doesn't work:

box silent noover       297 347 827 421 #dcdcdc
box silent noover 300 350 300 418 #000000ff
box silent inter 300 350 300 418 #ff00ff
box silent 300 350 824 418 #ff00ff

Because the box just shows what's underneath it - the plain rectangle we want as our progressbar border.

In fact, spock (http://dev.gentoo.org/~spock/index.php) shows us the way around this in his Emergence theme - take a look at /etc/splash/emergence/1024x768.cfg. In that he draws a 1-pixel wide "hollow rectangle" - it's not a single transparent rectangle, but rather 4 independent 1-pixel wide retangles forming a border.


File: /etc/splash/mytheme/1024x768.cfg
bgcolor=0

tx=162
ty=110
tw=700
th=548

text_x=250
text_y=743
text_size=19
text_color=0xffffff

box silent noover 300 750 824 768 #000000

box silent 297 347 827 350 #dcdcdc
box silent 297 347 300 421 #dcdcdc
box silent 297 418 827 421 #dcdcdc
box silent 824 347 827 421 #dcdcdc

box silent inter 300 350 300 418 #ff00ff
box silent 300 350 824 418 #ff00ff

pic=/etc/splash/mytheme/images/verbose-1024x768.jpg
silentpic=/etc/splash/mytheme/images/silent-1024x768.jpg

The above theme gives the progressbar a 3-pixel border by the use of 4 rectangles:

  • top edge:
    • progressbar(x0) - 3, progressbar(y0) - 3
      • to progressbar(x1) + 3, progressbar(y0)
  • left edge:
    • progressbar(x0) - 3, progressbar(y0) - 3
      • to progressbar(x0), progressbar(y1) + 3
  • bottom edge:
    • progressbar(x0) - 3, progressbar(y1)
      • to progressbar(x1) + 3, progressbar(y1) + 3
  • right edge:
    • progressbar(x1), progressbar(y0) - 3
      • to progressbar(x1) + 3, progressbar(y1) + 3

Where:

  • progressbar(x0), progressbar(y0) is the upper left corner of the progressbar.
  • progressbar(x1), progressbar(y1) is the lower right corner of the progressbar.

If working this out melts your brain as badly as it does mine, then I suggest you get a pen & a sheet of paper. I'm sure there are a few Gentoo geeks out there who can do this maths in their heads, but the rest of us'll have to plan it all out a few times on A4 & expect to make a few corrections in red ink. A good way to debug would be to comment out one line at a time & see which edge is affected.

[ edit]

Conclusion

The completed splashscreen in silent mode
Enlarge
The completed splashscreen in silent mode

I hope you find this article useful and that it encourages you to design you own themes. Please update the wiki if you find errors or discover a new way to do cool stuff with gensplash (http://dev.gentoo.org/~spock/projects/gensplash/) - I notice I haven't covered colour gradients at all. They are supported, so please feel free to experiment with them.

I haven't posted to the wiki the original artwork I used for this theme, because I'm not clear on the ownership of all its components - you can probably get a copy of it somewhere.

What would be really nice is a piece of Free artwork to go with this article - if you have one for which you own the copyright, please feel free to make it available & edit the article to accommodate it, but I'd be grateful if you'd be prepared to take on the full article & make the layout of the .cfg file fully-compatible with your artwork.

[ edit]

Contributors

The completed splashscreen in verbose mode
Enlarge
The completed splashscreen in verbose mode
  • Spock (http://dev.gentoo.org/~spock/index.php) for writing Gensplash (http://dev.gentoo.org/~spock/projects/gensplash/)! Thanks!
  • Andreoni.com, original artists of the Lamborghini & its logo on the pictures, Tux the penguin & the Gentoo G.
  • _mikec_ - from postings on the Gentoo Forums which inspired this HOWTO and for his work on the "GentooHorns" collage.
  • Joe Stroller - original article, written in a single 8-hour session. I spent the last 3 days building a splashscreen and wishing there was a HOWTO on it. When I saw postings on the Gentoo Forums with problems I had to address them. I don't anticipate maintaining or updating this article, so please volunteer!
posted on 2005-04-29 08:57 浙林龙哥 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/huqingyu/archive/2005/04/29/147299.html

<think>我们正在处理一个内核模块编译错误:`undefined reference to unregister_framebuffer`。这个错误通常发生在编译帧缓冲(framebuffer)设备驱动时,表明链接器无法找到`unregister_framebuffer`函数的定义。 ### 问题分析 1. **函数位置**:`unregister_framebuffer`函数定义在内核的帧缓冲子系统中,位于`drivers/video/fbdev/core/fbmem.c`文件。 2. **符号导出**:该函数通过`EXPORT_SYMBOL(unregister_framebuffer)`导出,因此可被模块使用。 3. **可能原因**: - 内核配置中未启用帧缓冲支持(`CONFIG_FB`)。 - 模块未正确链接到帧缓冲子系统(缺少依赖)。 - 内核版本差异导致函数名称或导出方式变化。 ### 解决方案 #### 1. 检查内核配置 确保内核配置启用了帧缓冲支持: ```bash # 检查当前内核配置 grep CONFIG_FB= /boot/config-$(uname -r) # 或检查内核源码目录下的.config文件 ``` 输出应为: ``` CONFIG_FB=y ``` 如果未启用,重新配置内核: ```bash make menuconfig ``` 导航至: ``` Device Drivers → Graphics support → Support for frame buffer devices ``` 启用该选项并重新编译内核。 #### 2. 添加正确的模块依赖 在模块的Makefile中,确保链接到帧缓冲核心模块(`fb`): ```makefile obj-m += my_fb_driver.o my_fb_driver-objs := my_fb_main.o my_fb_ops.o # 添加帧缓冲子系统依赖 my_fb_driver-y += $(addprefix $(srctree)/drivers/video/fbdev/core/, fbmem.o fb_sys_fops.o) # 不推荐直接包含内核源码文件 # 正确做法:使用内核构建系统自动解决依赖 ccflags-y := -I$(src)/include ``` 更推荐的做法是让构建系统自动处理依赖,只需确保模块声明了正确的依赖: ```c // 在模块代码中声明依赖 MODULE_DESCRIPTION("My FB Driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_VERSION("1.0"); ``` #### 3. 检查函数导出 确认目标内核中`unregister_framebuffer`函数被导出: ```bash # 查看内核符号表 grep unregister_framebuffer /proc/kallsyms # 或使用nm命令检查内核对象文件 nm vmlinux | grep unregister_framebuffer ``` 如果未找到,可能因为: - 内核版本较旧(<2.6.38)函数名不同 - 内核配置未启用`CONFIG_FB` #### 4. 使用正确的内核头文件 确保模块编译时使用目标内核的头文件: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) modules ``` #### 5. 版本适配 对于旧内核(<3.0),函数原型可能不同。参考内核源码: ```c // 新内核(>=2.6.38) void unregister_framebuffer(struct fb_info *fb_info); // 旧内核可能需要额外参数 int unregister_framebuffer(struct fb_info *fb_info); // 返回值非void ``` 在模块中处理兼容性: ```c #include <linux/version.h> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) static int my_unregister_framebuffer(struct fb_info *info) { return unregister_framebuffer(info); } #else static void my_unregister_framebuffer(struct fb_info *info) { unregister_framebuffer(info); } #endif ``` ### 错误修复示例 **问题代码**: ```c // 模块卸载函数 static void __exit myfb_exit(void) { unregister_framebuffer(my_fb_info); // 触发未定义引用 } ``` **修复后**: ```c #include <linux/fb.h> // 必须包含 static void __exit myfb_exit(void) { unregister_framebuffer(my_fb_info); } ``` ### 根本原因 `unregister_framebuffer`是帧缓冲设备注销的核心API[^1]。当模块未正确链接到内核的帧缓冲子系统时,链接器无法解析该符号,导致加载失败。 ### 验证步骤 1. 确认内核配置:`grep CONFIG_FB /boot/config-$(uname -r)` 2. 编译模块:`make -C /lib/modules/$(uname -r)/build M=$(pwd)` 3. 检查模块符号:`nm my_fb_driver.ko | grep unregister_framebuffer` - 输出应为:`U unregister_framebuffer`(未解决符号,加载时由内核解析) 4. 加载模块:`insmod my_fb_driver.ko` > **注意**:模块加载时,内核会自动解析未解决的符号(标记为`U`),前提是内核已导出该符号。 §§相关问题§§ 1. 如何在内核模块中正确注册和注销帧缓冲设备? 2. 内核模块编译时出现“未解决符号”错误有哪些常见原因? 3. 如何为不同内核版本编写兼容的帧缓冲驱动? 4. 内核配置中帧缓冲子系统的关键选项有哪些?</think>### 解决 `undefined reference to unregister_framebuffer` 编译错误 在内核模块编译中出现 `undefined reference to unregister_framebuffer` 错误,通常是由于帧缓冲(framebuffer)子系统相关依赖未正确处理导致的。以下是系统化的解决方案: --- #### 1. **检查内核配置(关键步骤)** `unregister_framebuffer` 函数需要启用帧缓冲支持: ```bash # 验证内核配置 grep CONFIG_FB= /boot/config-$(uname -r) # 应输出:CONFIG_FB=y 或 CONFIG_FB=m ``` 若未启用: 1. 运行内核配置: ```bash make menuconfig ``` 2. 启用路径: ``` Device Drivers → Graphics support → [*] Support for frame buffer devices ``` 3. 保存后重新编译内核: ```bash make -j$(nproc) && sudo make modules_install ``` > **注意**:某些硬件需要额外选项(如 `CONFIG_FB_[VENDOR]`),需根据硬件文档启用[^1]。 --- #### 2. **添加正确的模块依赖** 在模块的 Makefile 中确保链接帧缓冲核心: ```makefile # 正确示例 obj-m += my_fb_driver.o my_fb_driver-objs := main.o ssd1307fb_ops.o # 添加帧缓冲核心依赖 EXTRA_CFLAGS += -I$(src)/include/linux/fb.h KDIR ?= /lib/modules/$(shell uname -r)/build all: $(MAKE) -C $(KDIR) M=$(PWD) modules ``` 关键点: - 确保编译时包含 `drivers/video/fbdev/core/fbmem.o`(定义 `unregister_framebuffer`) - 使用目标内核的构建目录 (`/lib/modules/$(uname -r)/build`) --- #### 3. **验证函数导出状态** 检查内核是否导出该符号: ```bash # 查看内核符号表 grep unregister_framebuffer /proc/kallsyms # 或使用 nm nm vmlinux | grep unregister_framebuffer ``` 正常输出应类似: ``` ffffffffa0c45600 T unregister_framebuffer ``` 若未找到,说明: - 内核配置 `CONFIG_FB` 未启用 - 内核版本不兼容(函数名可能变化) --- #### 4. **修复模块代码(兼容性处理)** 在模块卸载函数中正确使用: ```c #include <linux/fb.h> // 必须包含 static void __exit myfb_exit(void) { /* 正确调用 */ unregister_framebuffer(fb_info); /* 资源清理 */ framebuffer_release(fb_info); } ``` 常见错误: - 未包含 `<linux/fb.h>` - `fb_info` 结构未正确初始化 - 未调用前置函数 `register_framebuffer()` --- #### 5. **内核版本兼容处理** 函数原型演变: ```c /* 内核版本 < 3.0 (可能返回 int) */ int unregister_framebuffer(struct fb_info *fb_info); /* 内核版本 ≥ 3.0 (void 返回) */ void unregister_framebuffer(struct fb_info *fb_info); ``` 使用条件编译: ```c #include <linux/version.h> #if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) static int my_unregister(struct fb_info *info) { return unregister_framebuffer(info); } #else static void my_unregister(struct fb_info *info) { unregister_framebuffer(info); } #endif ``` --- ### 根本原因 `unregister_framebuffer` 是帧缓冲子系统的核心注销函数[^1]: - 定义在 `drivers/video/fbdev/core/fbmem.c` - 通过 `EXPORT_SYMBOL(unregister_framebuffer)` 导出 - 依赖关系: ```mermaid graph LR A[驱动模块] -->|依赖| B(fbmem.ko) B -->|提供| C[unregister_framebuffer] D[CONFIG_FB] -->|启用| B ``` --- ### 验证流程 1. 确认配置: ```bash grep -e CONFIG_FB -e CONFIG_FB_CORE .config ``` 2. 编译模块: ```bash make -C /lib/modules/$(uname -r)/build M=$(pwd) modules ``` 3. 检查符号: ```bash nm my_module.ko | grep unregister_framebuffer # 正常输出应包含 U unregister_framebuffer (未解决符号) ``` 4. 加载测试: ```bash sudo insmod my_module.ko # 应无错误 ``` > **注意**:若问题持续,运行 `make clean` 后重新编译整个内核树。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值