Linux Kernel优化--initcall_debug

https://elinux.org/Main_Page 的文章中,提供了嵌入式linux的相关wiki。其中有专门一个章节用来讲启动时间并提供了几种优化方式:https://elinux.org/Boot_Time
本文主要使用initcall debug来定位哪个模块加载时间过长。


initcall debug

这个功能可以用于计算每个模块调用initcall的时间,这样就可以知道哪个模块初始化的时间过长。
魅族内核组吴章金发起了“嵌入式 Linux 知识库 (elinux.org) 中文翻译计划”,其中boot time的链接为:https://github.com/tinyclub/elinux/blob/master/zh/dev_portals/Boot_Time/Boot_Time.md


往cmdline传递参数

往cmdline传递以下两个参数initcall_debug=1 ignore_loglevel=1,在 /proc/cmdline 可以查看当前使用的cmdline情况。

传递这两个参数可以打开initcall_debug功能,dmesg的输出变为下面的格式,我们可以通过这里面的内容来进行Kernel的优化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[    6.302837] initcall cdns3_driver_platform_register+0x0/0x24 returned 0 after 73878 usecs
[ 6.311062] calling ehci_hcd_init+0x0/0x70 @ 1
[ 6.315596] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 6.322165] initcall ehci_hcd_init+0x0/0x70 returned 0 after 6411 usecs
[ 6.328790] calling ehci_platform_init+0x0/0x60 @ 1
[ 6.333762] ehci-platform: EHCI generic platform driver
[ 6.339365] initcall ehci_platform_init+0x0/0x60 returned 0 after 5467 usecs
[ 6.346423] calling xhci_hcd_init+0x0/0x20 @ 1
[ 6.350971] initcall xhci_hcd_init+0x0/0x20 returned 0 after 0 usecs
[ 6.357353] calling xhci_plat_init+0x0/0x34 @ 1
[ 6.362425] initcall xhci_plat_init+0x0/0x34 returned 0 after 428 usecs
[ 6.369058] calling usb_storage_driver_init+0x0/0x48 @ 1
[ 6.374593] usbcore: registered new interface driver usb-storage
[ 6.380702] initcall usb_storage_driver_init+0x0/0x48 returned 0 after 6063 usecs
[ 6.388223] calling usb3503_init+0x0/0x68 @ 1
[ 6.392925] initcall usb3503_init+0x0/0x68 returned 0 after 239 usecs
[ 6.399384] calling ci_hdrc_platform_register+0x0/0x24 @ 1
[ 6.405166] initcall ci_hdrc_platform_register+0x0/0x24 returned 0 after 79 usecs
[ 6.412671] calling ci_hdrc_usb2_driver_init+0x0/0x20 @ 1
[ 6.418345] initcall ci_hdrc_usb2_driver_init+0x0/0x20 returned 0 after 171 usecs


倒叙排列输出时间

有了上面串口的信息,我们可以通过将函数名和与之对应的时间提取出来,然后倒叙排列,输出到excel文件中,以直观的方式展示出来。

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
#!/usr/bin/python
#-*- coding:utf-8 -*-

import operator
import xlwt

file = open("./cal_time/kernel-log.txt")
line = 0
list = []

while 1:
content = file.readline()
if not content:
break
line = line+1
content=content.strip('\n')
usecs_part = content.endswith("usecs")
if usecs_part == 1:
# 获取usecs参数
#print("%d: %s\n" %(line,content))
sec_start_index = content.find("after")+6
sec_end_index = content.find("usecs")-1
useconds = content[sec_start_index:sec_end_index]
usec = int(useconds)
#print("%d, %d, %d, %s\n" %(sec_start_index, sec_end_index, usec, useconds))

# 获取函数名
func_start_index = content.find("initcall")+9
func_end_index = content.find("+")
func_name = content[func_start_index:func_end_index]
#print("%d, %d, %s\n" %(func_start_index, func_end_index, func_name))
list.append((usec, func_name))

# 采用降序排序
list.sort(reverse = True)
#print(list)

# 写入到excel表格中
data=xlwt.Workbook()
table=data.add_sheet("函数耗时统计")
table.write(0, 0, u'函数名')
table.write(0, 1, u'耗时')

for i in range(0, len(list)):
for j in range(0, 2):
table.write(i+1, 1-j, list[i][j])
data.save("output.xls")

输出的结果如下:
输出结果

Title:Linux Kernel优化--initcall_debug

Author:Victor Huang

Time:2019-06-08 / 13:06

Link:http://wowothink.com/127f8b72/

License: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)