Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1292290
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2015-09-28 14:41:12

[FAQ14415]如何开启early printk调试kernel?
2015-06-29
软件分支GB3GB5JB2JB3...
FAQs 12 of 109
如何用MMU保护buddy system? 异常发生后如何将log里对应的地址转换为所在的文件和行号?

内容

[DESCRIPTION]
在开发阶段会遇到各种不开机问题,甚至连kernel uart log还没吐出来就crash了。
这时你需要early printk功能让kernel更早将kernel log吐到uart,看到crashlog。
 
[SOLUTION]
ARM32位版本:
ARM32原生early printk porting比较麻烦,这里放弃使用原生early printk。
1. 在alps/kernel/arch/arm/mm/mmu.c里添加如下代码:
[C/C++]hide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <linux/console.h>
 
#include <linux/io.h>
 
#include <mach/mt_reg_base.h>
 
 
 
#define UART_BASE UART1_BASE /* 根据需要修改,比如有些平台是AP_UART0_BASE */
 
#define EARLY_BASE (VMALLOC_START - SZ_1M)
 
static void mtuart_printch(char ch)
 
{
 
 while (!(readl_relaxed((void __iomem *)EARLY_BASE + 0x14)&0x20));
 
 writel_relaxed(ch, (void __iomem *)EARLY_BASE);
 
}
 
 
 
static void early_write(struct console *con, const char *s, unsigned n)
 
{
 
 while (n-- > 0) {
 
 if (*s == '\n')
 
 mtuart_printch('\r');
 
 mtuart_printch(*s);
 
 s++;
 
 }
 
}
 
 
 
static void __init setup_early_printk(void)
 
{
 
 static struct console early_console_dev = {
 
 .name = "earlycon",
 
 .write = early_write,
 
 .flags = CON_PRINTBUFFER|CON_BOOT,
 
 .index = -1,
 
 };
 
 struct map_desc mt_uart_desc = {
 
 .virtual = EARLY_BASE,
 
 .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(UART_BASE)),
 
 .length = SZ_4K,
 
 .type = MT_DEVICE,
 
 };
 
 
 
 create_mapping(&mt_uart_desc, false);
 
 register_console(&early_console_dev);
 
}
 
2. 同时在map_lowmem()函数最后添加:
[C/C++]hide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
static void __init map_lowmem(void)
 
{
 
 ......
 
#ifdef CONFIG_DEBUG_RODATA
 
 start = __pa(_stext) & SECTION_MASK;
 
 map.pfn = __phys_to_pfn(start);
 
 map.virtual = __phys_to_virt(start);
 
 map.length = ALIGN(lowmem_limit - start, PMD_SIZE);
 
 map.type = MT_MEMORY;
 
 
 
 create_mapping(&map, true);
 
#endif
 
 setup_early_printk(); /* add this line */
 
}
 
3.  根据实际平台修改第1步里的UART_BASE。
 
ARM64位版本:
1. 检查alps/kernel-3.10/arch/arm64/configs/$proj_defconfig或alps/kernel-3.10/arch/arm64/configs/$proj_debug_defconfig是否有开启early printk功能(默认开启),如果没有开启,请修改为:
CONFIG_EARLY_PRINTK=y
 
2. 在bootable/bootloader/lk/platform/$platform/include/platform/mt_reg_base.h的COMMANDLINE_TO_KERNEL宏添加early printk参数:
#define COMMANDLINE_TO_KERNEL "console=tty0 console=ttyMT3,921600n1 root=/dev/ram vmalloc=496M slub_max_order=0 slub_debug=O earlyprintk=uart8250-32bit,0x11002000"
上面蓝字部分为添加的earlyprintk参数。其中的0x11002000为AP UART0寄存器地址,每个平台不同,需要根据不同平台修改才行:
MT6752/MT6732/MT6753/MT6735/MT6795/MT6595:0x11002000
MT6580:0x11005000
其他的具体请看对应的alps/kernel-3.10/arch/arm64/boot/dts/mtxxxx.dtsi文件里的AP_UART0节点。
阅读(2222) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~