When Linux kernel panic, what can we do ?
2011-10-26 15:37
381 查看
注意: 版权所有, 转载请注明出处.
Caution: All rights reserved, Please indicate the source if reproduce.
Hardware: Freescale iMX515
Software: Linux kernel 2.6.31
Target requirement: show "boot failed !" in LCD while Linux kernel panic.
Technology methods: use Notifier chains of kernel to do.
Reference to:
[1]. http://bbs.chinaunix.net/thread-2011776-1-1.html
[2]. Linux kernel source code tree: /include/linux/notifier.h, kernel/notifier.c
Modification souce code:
drivers/video/console/fbcon.c
kernel/panic.c
1. modify drivers/video/console/fbcon.c
1.1 modify function fbcon_init()
1.2 add below codes in this file
2. modify kernel/panic.c
2.1 add the code in this file
extern int lcd_notifier_call_chain(unsigned long val, void *v);
2.2 modify function panic()
3. conifg Kernel
#make menuconfig
Select this menu items
Device Drivers ---> Graphics support ---> [*] Bootup logo ---> [*] Standard 224-color Linux logo (NEW)
4. build Kernel
#make -j 4; make uImage
Caution: All rights reserved, Please indicate the source if reproduce.
Hardware: Freescale iMX515
Software: Linux kernel 2.6.31
Target requirement: show "boot failed !" in LCD while Linux kernel panic.
Technology methods: use Notifier chains of kernel to do.
Reference to:
[1]. http://bbs.chinaunix.net/thread-2011776-1-1.html
[2]. Linux kernel source code tree: /include/linux/notifier.h, kernel/notifier.c
Modification souce code:
drivers/video/console/fbcon.c
kernel/panic.c
1. modify drivers/video/console/fbcon.c
1.1 modify function fbcon_init()
static void fbcon_init(struct vc_data *vc, int init) { /* omit ... */ /* show boot information in LCD */ #if defined(CONFIG_LOGO_LINUX_CLUT224) show_boot.info = registered_fb[con2fb_map[vc->vc_num]]; show_boot.ops = show_boot.info->fbcon_par; show_boot.vc = vc; show_boot.p = &fb_display[vc->vc_num]; ret = kernel_thread(show_boot_info_thread, (void *) &show_boot, CLONE_KERNEL); if(ret < 0) { pr_err("Failed to start show_boot_info_thread daemon\n"); } else { pr_notice("Successful to start show_boot_info_thread daemon\n"); } #endif /* CONFIG_LOGO_LINUX_CLUT224 */ }
1.2 add below codes in this file
#if defined(CONFIG_LOGO_LINUX_CLUT224) /* Wenxy add begin, 20111014 */ struct show_boot_in_lcd { struct fbcon_ops *ops; struct vc_data *vc; struct fb_info *info; struct display *p; }; static struct show_boot_in_lcd show_boot; static RAW_NOTIFIER_HEAD(lcd_show_chain); /* show error information in LCD */ /* LCD show error information */ static int lcd_tip_error(struct notifier_block *this, unsigned long event, void *ptr) { struct vc_data *vc; struct fb_info *info; struct fbcon_ops *ops; struct display *p; int yy; int xx; int fg; int bg; unsigned int len; unsigned char tips[]="b o o t f a i l e d ! "; if(!show_boot.ops) { return -EINVAL; } vc = show_boot.vc; info = show_boot.info; ops = show_boot.ops; p = show_boot.p; xx = 5; /* 62 */ yy = 28; fg = 0x04; /* red: 0x04 */ bg = 0x7; /* vc->vc_halfcolor; */ len = strlen(tips)/2; ops->putcs(vc, info, (unsigned short *)tips, len, real_y(p, yy), real_y(p, xx), fg, bg); return 0; } static struct notifier_block lcd_notifier_error = { .notifier_call = lcd_tip_error, }; int lcd_notifier_call_chain(unsigned long val, void *v) { return raw_notifier_call_chain(&lcd_show_chain, 1, NULL); } EXPORT_SYMBOL(lcd_notifier_call_chain); /* Show boot information in LCD */ static int show_boot_info_thread(void * dummy) { struct vc_data *vc; struct fb_info *info; struct fbcon_ops *ops; struct display *p; const unsigned short *s; int count; int yy; int xx; int fg; int bg; int softback_lines; int mode; unsigned int n, index, len1, len2; #define FM_VERSION "Firmware version: " /* UTS_RELEASE */ unsigned char version[256], substr1[128], substr2[128]; unsigned char bar[]=" "; unsigned int time_count, pass_count, bar_count; #define SLEEP_MS 100 /* millisecond, 100,500 */ #define BOOT_KERNEL_TIME 10 /* second, 10 */ #define BAR_LEN 90 /* boot progress bar length */ if(!dummy) { return -EINVAL; } vc = ((struct show_boot_in_lcd *)dummy)->vc; info = ((struct show_boot_in_lcd *)dummy)->info; ops = ((struct show_boot_in_lcd *)dummy)->ops; p = ((struct show_boot_in_lcd *)dummy)->p; time_count = (BOOT_KERNEL_TIME*1000)/SLEEP_MS; pass_count = 1; /* time_count = 180; pass_count = 1; bar_count = BAR_LEN/time_count; */ /* register notifier block */ if(raw_notifier_chain_register(&lcd_show_chain, &lcd_notifier_error)) { pr_warning("Warning: into %s, %s, raw_notifier_chain_register call failed\n", __FILE__, __FUNCTION__); } /* show version in LCD */ memset(substr1, 0, sizeof(substr1)); memset(substr2, 0, sizeof(substr2)); memset(version, 0, sizeof(version)); memcpy(substr1, FM_VERSION, sizeof(FM_VERSION)); memcpy(substr2, UTS_RELEASE, sizeof(UTS_RELEASE)); len1 = 2*strlen(FM_VERSION); index = 0; for(n = 0; n < len1; n+=2) { version = substr1[index++]; version[n+1] = ' '; } len2 = 2*strlen(UTS_RELEASE); index = 0; for(n = 0; n < len2; n+=2) { version[len1 + n] = substr2[index++]; version[len1 + n+1] = ' '; } /*pr_notice("Debug:%s\n", version);*/ xx = 55; /* 62 */ yy = 28; fg = 0x00; /* 0x00 */ bg = 0x7; /* vc->vc_halfcolor; */ ops->putcs(vc, info, (unsigned short *)version, (len1+len2)/2, real_y(p, yy), real_y(p, xx), fg, bg); /* draw progress bar in LCD */ xx = 5; yy = 26; fg = 0x7; bg = fg; ops->putcs(vc, info, (unsigned short *)bar, BAR_LEN, real_y(p, yy), real_y(p, xx), fg, bg); while(pass_count <= time_count) { xx = 5; yy = 26; fg = 0x2; bg = 0x2; ops->putcs(vc, info, (unsigned short *)bar, pass_count>BAR_LEN?BAR_LEN:pass_count, \ real_y(p, yy), real_y(p, xx), fg, bg); /* ops->putcs(vc, info, (unsigned short *)bar, pass_count*bar_count, \ real_y(p, yy), real_y(p, xx), fg, bg); */ pass_count++; #if 0 ops->cursor_flash = 0; /* stop cursor flash */ vc->vc_x = 0; /* Cursor position */ vc->vc_y = 0; vc->vc_deccm = 0; /* Cursor cannot Visible */ #endif mdelay(SLEEP_MS); } pr_notice("Successful to exit show_boot_info_thread daemon\n"); #if 0 vc->vc_deccm = 1; ops->cursor_flash = 1; #endif /* unregister notifier block */ if(raw_notifier_chain_unregister(&lcd_show_chain, &lcd_notifier_error)) { pr_warning("Warning: into %s, %s, raw_notifier_chain_unregister call failed\n", __FILE__, __FUNCTION__); } return 0; } /* Wenxy add end */ #endif /* LOGO_LINUX_CLUT224 */
2. modify kernel/panic.c
2.1 add the code in this file
extern int lcd_notifier_call_chain(unsigned long val, void *v);
2.2 modify function panic()
/** * panic - halt the system * @fmt: The text string to print * * Display a message, then perform cleanups. * * This function never returns. */ NORET_TYPE void panic(const char * fmt, ...) { static char buf[1024]; va_list args; long i; #if defined(CONFIG_LOGO_LINUX_CLUT224) /* notification show error information in LCD */ if(lcd_notifier_call_chain(1, NULL)) { pr_warning("Warning: into %s, %s, lcd_notifier_call_chain call failed\n", __FILE__, __FUNCTION__); } /*mdelay(1 * 1000);*/ #endif /* LOGO_LINUX_CLUT224 */ /* * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... */ preempt_disable(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); #ifdef CONFIG_DEBUG_BUGVERBOSE dump_stack(); #endif /* omit ... */ }
3. conifg Kernel
#make menuconfig
Select this menu items
Device Drivers ---> Graphics support ---> [*] Bootup logo ---> [*] Standard 224-color Linux logo (NEW)
4. build Kernel
#make -j 4; make uImage
相关文章推荐
- What should we do when we find an issue
- what we can do after 35, programmers
- What should we do when meet a crash in android?
- What's the use of do while(0) when we define a macro?
- What we can do in "Page" class 页面基类功能扩展汇总
- What we can do 专题
- What can we do in the CacheMetaData Method of Activity
- openstack!what can we do ?
- What should we do when meet a crash in android
- Why compilers have failed and what we can do about it
- What should we do when meet a crash in android?
- What Does __read_mostly In The Linux Kernel Do?
- What we can do with App.config?
- What can we do?
- What is default gateway? How can we find it in Linux?
- VS 2005 Web Project System: What is it and why did we do it?
- Linux Kernel Panic 解决思路
- weblogic,who am i?what can i do?
- 1715 When Can We Meet?
- HOWTO do Linux kernel development - take 3 (中文版)