Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Segmentation fault on openwrt for ili9341 based TFT #234

Closed
bogdanul2003 opened this issue Jan 28, 2015 · 11 comments
Closed

Segmentation fault on openwrt for ili9341 based TFT #234

bogdanul2003 opened this issue Jan 28, 2015 · 11 comments

Comments

@bogdanul2003
Copy link

Hi,

I'm using this repo to make fbtft to work on openwrt: https://github.com/GBert/openwrt-misc/tree/master/fbtft

All compiles ok and I execute these commands:
insmod fb_defio
insmod fb
insmod fbtft
insmod fb_ili9341
insmod fbtft_device name=tm022hdh26 busnum=32766 gpios=reset:11,led:12,dc:13 rotate=270

When I load fbtft_device I get a segmentation fault that I could trace to fbtft-core.c in fbtft_framebuffer_alloc() function at line "par->info = info;"

It seems that par was not allocated when the call to framebuffer_alloc() was made. Do you know what the problem may be ?

Thank you,
Bogdan

@notro
Copy link
Owner

notro commented Jan 28, 2015

Is this what you get in the kernel log?

BUG: unable to handle kernel NULL pointer dereference ...

The only reason I can see for info->par to be NULL, is when sizeof(struct fbtft_par) is zero.
Try adding before the offending line: printk("info->par=%p\n", info->par);

@bogdanul2003
Copy link
Author

Hi notro,

This is weird because the size of fbtft_par is 448.
[ 237.360000] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8 sizeof(struct fbtft_par):448
[ 237.360000] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9 info->par: (null)

this is right after the framebuffer_alloc() call.

This is dmesg output:

[ 237.360000] fbtft_device: SPI devices registered:
[ 237.360000] fbtft_device: m25p80 spi0.0 25000kHz 8 bits mode=0x00
[ 237.360000] fbtft_device: spidev spi19.0 1kHz 8 bits mode=0x00
[ 237.360000] fbtft_device: 'fb' Platform devices registered:
[ 237.360000] fbtft_device: Deleting spi19.0

[ 237.360000] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!8 sizeof(struct fbtft_par):448
[ 237.360000] !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9 info->par: (null)
[ 237.360000] CPU 0 Unable to handle kernel paging request at virtual address 00000008, epc == 8332b6a8, ra == 8332b6a8
[ 237.360000] Oops[#1]:
[ 237.360000] CPU: 0 PID: 2041 Comm: insmod Not tainted 3.14.28 #2
[ 237.360000] task: 828ad320 ti: 831ea000 task.ti: 831ea000
[ 237.360000] $ 0 : 00000000 00000000 0000002e 00000007
[ 237.360000] $ 4 : 00000007 00000000 00000000 00000036
[ 237.360000] $ 8 : 00000035 21212121 21212121 21212121
[ 237.360000] $12 : 00000000 ffffff80 00000000 21212121
[ 237.360000] $16 : 833fd000 8283280c 829426b8 8287f500
[ 237.360000] $20 : 00000000 00004000 828326bc 00000010
[ 237.360000] $24 : 00000001 800cddd0
[ 237.360000] $28 : 831ea000 831ebb90 833c5410 8332b6a8
[ 237.360000] Hi : 00000e10
[ 237.360000] Lo : 00003840
[ 237.360000] epc : 8332b6a8 fbtft_framebuffer_alloc+0x4cc/0x768 [fbtft]
[ 237.360000] Not tainted
[ 237.360000] ra : 8332b6a8 fbtft_framebuffer_alloc+0x4cc/0x768 [fbtft]
[ 237.360000] Status: 1000fc03 KERNEL EXL IE
[ 237.360000] Cause : 00800008
[ 237.360000] BadVA : 00000008
[ 237.360000] PrId : 00019374 (MIPS 24Kc)
[ 237.360000] Modules linked in: fbtft_device(+) fb_ili9341 fbtft spi_gpio_custom ath9k ath9k_common pppoe ppp_async iptable_nat ath9k_hw ath pppox ppp_generic nf_nat_ipv4 nf_conntrack_ipv6 nf_conntrack_ipv4 mac80211 ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_id xt_conntrack xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_CT spidev spi_gpio slhc nf_nat_irc nf_nat_ftp nf_nat nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack_irc nf_conntrack_ftp nf_conntrack iptable_raw iptable_mangle iptable_filter ipt_REJECT ip_tables crc_ccitt compat configs ledtrig_usbdev ip6t_REJECT ip6table_raw ip6table_mangle ip6table_filter ip6_tables x_tables ipv6 fb_defio ohci_platform ohci_hcd ehci_platform ehci_hcd gpio_button_hotplug usbcore nls_base usb_common
[ 237.360000] Process insmod (pid: 2041, threadinfo=831ea000, task=828ad320, tls=773d2440)
[ 237.360000] Stack : 838297e8 00000000 00000000 00000036 8287f810 00000014 00000140 00000000
[ 237.360000] 000000f0 00025800 c062e000 8287f710 8287f500 8283280c 8287f500 803b0000
[ 237.360000] 8287f500 829426b8 00000000 829450fc 82940570 8332b9c4 8287f508 803b0000
[ 237.360000] 00000008 801263e4 8287f500 8287f500 828327d0 803b0000 00000008 803a0000
[ 237.360000] 80330000 801260dc 00000001 8287f508 83317000 8008c80c 00000000 00000000
[ 237.360000] ...
[ 237.360000] Call Trace:
[ 237.360000] [<8332b6a8>] fbtft_framebuffer_alloc+0x4cc/0x768 [fbtft]
[ 237.360000] [<8332b9c4>] fbtft_probe_common+0x80/0x418 [fbtft]
[ 237.360000] [<801260dc>] driver_probe_device+0xc8/0x21c
[ 237.360000] [<800e56f4>] bus_for_each_drv+0x9c/0xac
[ 237.360000] [<8010ae60>] device_attach+0x78/0x9c
[ 237.360000] [<800e579c>] bus_probe_device+0x38/0xc8
[ 237.360000] [<8010ad0c>] device_add+0x424/0x4f8
[ 237.360000] [<8024be88>] spi_add_device+0x118/0x16c
[ 237.360000] [<8024ca58>] spi_new_device+0x90/0xbc
[ 237.360000] [<82947560>] init_module+0x560/0x6dc [fbtft_device]
[ 237.360000] [<8011ca9c>] do_one_initcall+0xf0/0x194
[ 237.360000] [<801aa72c>] load_module+0x1508/0x1ae4
[ 237.360000] [<80074458>] SyS_init_module+0xbc/0xd4
[ 237.360000] [<8006283c>] handle_sys+0x11c/0x140
[ 237.360000]
[ 237.360000]
[ 237.360000] Code: 3c048333 0c0a4b93 2484e6b0 <8e850008> 3c048333 0c0a4b93 2484e6e4 3c048333 2484e70c
[ 237.360000] ---[ end trace 581d40f1b3c01564 ]---

I'll keep digging later ... I'm sure there is an obvious thing that at the moment is not so obvious :)

@bogdanul2003
Copy link
Author

It seems that there is something wrong with my buildtree.
The size of fb_info is not the same in fbtft-coare.c and fbsysfs.c where framebuffer_alloc() is implemented.

So in fbtft-coare.c the size of fb_info is 652 and in fbsysfs.c the size of fb_info is 596, a huge difference. Both files include <linux/fb.h> but it seems that it doesn't point to the same .h file.
Do you know how I could see which .h file is used at compile time ?

Regards,
Bogdan

@notro
Copy link
Owner

notro commented Jan 29, 2015

I don't know much about the build details, but the .o.cmd files lists headers.
You probably better of asking the guy who put this together.

@bogdanul2003
Copy link
Author

Hi Notro,

I contacted that guy but he can't help me. I think that fb and fbtft use the same fb.h file but the modules are compiled with different defines ("-D").
I did some more digging and found out that fb_info structure has some #ifdefs inside:

struct fb_info {
    atomic_t count;
    int node;
    int flags;
    struct mutex lock;      /* Lock for open/release/ioctl funcs */
    struct mutex mm_lock;       /* Lock for fb_mmap and smem_* fields */
    struct fb_var_screeninfo var;   /* Current var */
    struct fb_fix_screeninfo fix;   /* Current fix */
    struct fb_monspecs monspecs;    /* Current Monitor specs */
    struct work_struct queue;   /* Framebuffer event queue */
    struct fb_pixmap pixmap;    /* Image hardware mapper */
    struct fb_pixmap sprite;    /* Cursor hardware mapper */
    struct fb_cmap cmap;        /* Current cmap */
    struct list_head modelist;      /* mode list */
    struct fb_videomode *mode;  /* current mode */

**#ifdef CONFIG_FB_BACKLIGHT**
    /* assigned backlight device */
    /* set before framebuffer registration, 
       remove after unregister */
    struct backlight_device *bl_dev;

    /* Backlight level curve */
    struct mutex bl_curve_mutex;    
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
**#endif**
**#ifdef CONFIG_FB_DEFERRED_IO**
    struct delayed_work deferred_work;
    struct fb_deferred_io *fbdefio;
**#endif**

Files from fbtft are compiled with these defines (-DCC_HAVE_ASM_GOTO -DCONFIG_FB_SYS_FILLRECT=1 -DCONFIG_FB_SYS_COPYAREA=1 -DCONFIG_FB_SYS_IMAGEBLIT=1 -DCONFIG_FB_SYS_FOPS=1 -DCONFIG_FB_TFT_FBTFT_DEVICE=1 -DCONFIG_FB_TFT=1 -DCONFIG_FB_TFT_ILI9341=1 -DCONFIG_FB_DEFERRED_IO=1):
CC_HAVE_ASM_GOTO
CONFIG_FB_SYS_FILLRECT=1
CONFIG_FB_SYS_COPYAREA=1
CONFIG_FB_SYS_IMAGEBLIT=1
CONFIG_FB_SYS_FOPS=1
CONFIG_FB_TFT_FBTFT_DEVICE=1
CONFIG_FB_TFT=1
CONFIG_FB_TFT_ILI9341=1
CONFIG_FB_DEFERRED_IO=1
This makes fb_info definition from fbtft to also include "struct delayed_work deferred_work; struct fb_deferred_io *fbdefio;" which increases the size of the structure.

Now fbsysfs.c from fb module is not compiled with any of these flags which will cause the compiler to use a smaller fb_info structure to be used inside fb core.

I'll try to fix this but in case you already know how to fix this please leave a comment.
With what defines do you compile fb for raspberry pi ?

@notro
Copy link
Owner

notro commented Feb 1, 2015

Why don't you just build a new kernel instead of trying to make this hack work?

FBTFT relies on CONFIG_FB being set, and when CONFIG_FB_TFT is set, these are selected as well: https://github.com/notro/fbtft/blob/master/Kconfig#L1

If CONFIG_FB=y in your running kernel, then you can't change the fb_info structure, it's already set.
Adding missing defines in loadable modules will break things. You might make it work, because they are at the end of fb_info, but why go to all this trouble?
Building a new kernel solve all these problems.

@bogdanul2003
Copy link
Author

This is the first time I had to deal with linux kernel and i didn't get all the tricks yet :)
What do you mean by building a new kernel? I rebuild(recompile) the kernel but each time fbsysfs.c is not compiled with -DCONFIG_FB_DEFERRED_IO which gives all those problems.
Is it because I build fbtft as an ordinary package ? I don't know if you are familiar with opnewrt.

@notro
Copy link
Owner

notro commented Feb 1, 2015

Ok, I thought you were trying to patch this on to a already built kernel.
If you need to build fbtf as out-of-tree modules, you can enable one of the drivers that select FB_DEFERRED_IO: http://lxr.free-electrons.com/source/drivers/video/fbdev/Kconfig
That would solve the dependency.

Or you can copy fbtft into the kernel tree: https://github.com/notro/fbtft/blob/master/README

@bogdanul2003
Copy link
Author

Hi Notro,

I know this is no longer an issue regarding fbtft module but I'm still struggling to make linux framebuffer to compile with the right flags.

I enabled FB_AUO_K190X from "make kernel_menuconfig" and I checked my .config file from build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.14.28 and I found this :
CONFIG_FB_DEFERRED_IO=y

It seems that deferred IO is defined but it's not used at compile time. For example I enabled FB_AUO_K190X which depends on FB_DEFERRED_IO and after compilation I looked in .auo_k190x.o.cmd and there is no trace of -DCONFIG_FB_DEFERRED_IO. All other .c files of linux framebuffer are not compiled with the right flags. Only fbtft .c files are compiled with -DCONFIG_FB_DEFERRED_IO.

Any idea why this is happening ?
One more question: if CONFIG_FB_DEFERRED_IO=y in .config file all files should be compiled with -DCONFIG_FB_DEFERRED_IO=1 ? How does the build tool choose what files are compiled with what define flags ?

@notro
Copy link
Owner

notro commented Feb 3, 2015

I don't know much about kbuild, but if CONFIG_FB_DEFERRED_IO is set in .config, then the kernel will have support for it. You can verify that it has been built by checking that drivers/video/fbdev/core/fb_defio.o exists.

Why not put the drivers in-tree as explained by the README and your out-of-tree building problems go away?

@bogdanul2003
Copy link
Author

Good thing you mentioned about kbuild. I looked it up and it seems that frame buffer files don't need any extra define flags like -DCONFIG_FB_DEFERRED_IO=1 because all defines are made in include/generated/autoconf.h which is included by all files (indirectly).
Now fb_info structure has the same size everywhere and the module loads without a segmentation fault.
But now it seems that I'm not allowed to use a gpio pin bigger than 1 for CS:
[ 185.490000] fbtft_device: SPI devices registered:
[ 185.490000] fbtft_device: m25p80 spi0.0 25000kHz 8 bits mode=0x00
[ 185.490000] fbtft_device: spidev spi19.0 1kHz 8 bits mode=0x00
[ 185.490000] fbtft_device: 'fb' Platform devices registered:
[ 185.490000] spi_gpio spi_gpio.19: cs17 >= max 1
[ 185.490000] fbtft_device: spi_new_device() returned NULL
[ 185.490000] fbtft_device: failed to register SPI device

If I use CS=0 all is ok the problem is that GPIO 0 is assigned for something else.
I'll try to fix this too.
Thanks a lot for your answers and nice job with fbtft driver.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants