console_init
来源:互联网 发布:网络复活赛 编辑:程序博客网 时间:2024/05/08 04:37
从start_kernel 会调用console_init 来初始化串口
void __init console_init(void)
{
initcall_t *call;
/* Setup the default TTY line discipline. */
n_tty_init();
/*
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
call++;
}
}
从console_init的实现可以看出会依次调用__con_initcall_start和__con_initcall_end的函数
从system.map 中可以看到在__con_initcall_start和__con_initcall_end 之间有四个函数
ffff0000090bc9a0 T __con_initcall_start
ffff0000090bc9a0 t __initcall_con_init
ffff0000090bc9a0 T __initcall_end
ffff0000090bc9a8 t __initcall_hvc_console_init
ffff0000090bc9b0 t __initcall_univ8250_console_init
ffff0000090bc9b8 t __initcall_mvebu_uart_console_init
ffff0000090bc9c0 T __con_initcall_end
其运行时的callstack如下:
[ 0.021084] Hardware name: (null) (DT)
[ 0.024865] Call trace:
[ 0.027334] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.032787] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.037888] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.042989] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.048706] [<ffff000008d0c258>] con_init+0x240/0x264
[ 0.053806] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.059084] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.064535] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.069466] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.077289] Hardware name: (null) (DT)
[ 0.081069] Call trace:
[ 0.083533] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.088984] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.094084] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.099184] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.104899] [<ffff000008d0c414>] hvc_console_init+0x18/0x24
[ 0.110527] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.115802] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.121253] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.126181] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.134004] Hardware name: (null) (DT)
[ 0.137785] Call trace:
[ 0.140249] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.145700] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.150800] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.155899] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.161615] [<ffff000008d0cb64>] univ8250_console_init+0x2c/0x3c
[ 0.167681] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.172957] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.178408] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.183335] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.191158] Hardware name: (null) (DT)
[ 0.194938] Call trace:
[ 0.197402] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.202853] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.207953] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.213052] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.218768] [<ffff000008d0d840>] cdns_uart_console_init+0x14/0x20
[ 0.224923] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.230198] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.235649] [<ffff0000080811c8>] 0xffff0000080811c8
我们以univ8250_console_init为例
static int __init univ8250_console_init(void)
{
if (nr_uarts == 0)
return -ENODEV;
serial8250_isa_init_ports();
register_console(&univ8250_console);
return 0;
}
console_initcall(univ8250_console_init);
原来就是在univ8250_console_init 中直接调用register_console,这个函数是所有console driver 必须调用的
其次通过console_initcall将自己也就是univ8250_console_init 添加到__con_initcall_start和__con_initcall_end 之间
可以看到console_initcall 是放在con_initcall.init 这个section中
#define console_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.con_initcall.init) = fn
而con_initcall.init 是让在__con_initcall_start和__con_initcall_end 之间的.
#define CON_INITCALL \
VMLINUX_SYMBOL(__con_initcall_start) = .; \
KEEP(*(.con_initcall.init)) \
VMLINUX_SYMBOL(__con_initcall_end) = .;
所以要注册自己的console的driver的话,可以通过console_initcall 将自己添加到__con_initcall_start和__con_initcall_end,这样kernel初始化的时候就会自动调用init函数.
void __init console_init(void)
{
initcall_t *call;
/* Setup the default TTY line discipline. */
n_tty_init();
/*
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
call++;
}
}
从console_init的实现可以看出会依次调用__con_initcall_start和__con_initcall_end的函数
从system.map 中可以看到在__con_initcall_start和__con_initcall_end 之间有四个函数
ffff0000090bc9a0 T __con_initcall_start
ffff0000090bc9a0 t __initcall_con_init
ffff0000090bc9a0 T __initcall_end
ffff0000090bc9a8 t __initcall_hvc_console_init
ffff0000090bc9b0 t __initcall_univ8250_console_init
ffff0000090bc9b8 t __initcall_mvebu_uart_console_init
ffff0000090bc9c0 T __con_initcall_end
其运行时的callstack如下:
[ 0.021084] Hardware name: (null) (DT)
[ 0.024865] Call trace:
[ 0.027334] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.032787] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.037888] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.042989] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.048706] [<ffff000008d0c258>] con_init+0x240/0x264
[ 0.053806] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.059084] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.064535] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.069466] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.077289] Hardware name: (null) (DT)
[ 0.081069] Call trace:
[ 0.083533] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.088984] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.094084] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.099184] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.104899] [<ffff000008d0c414>] hvc_console_init+0x18/0x24
[ 0.110527] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.115802] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.121253] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.126181] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.134004] Hardware name: (null) (DT)
[ 0.137785] Call trace:
[ 0.140249] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.145700] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.150800] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.155899] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.161615] [<ffff000008d0cb64>] univ8250_console_init+0x2c/0x3c
[ 0.167681] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.172957] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.178408] [<ffff0000080811c8>] 0xffff0000080811c8
[ 0.183335] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.63-10.g63e7b5f-default+ #1
[ 0.191158] Hardware name: (null) (DT)
[ 0.194938] Call trace:
[ 0.197402] [<ffff00000808a470>] dump_backtrace+0x0/0x178
[ 0.202853] [<ffff00000808a608>] show_stack+0x20/0x28
[ 0.207953] [<ffff0000083f3a18>] dump_stack+0x8c/0xac
[ 0.213052] [<ffff00000811d658>] register_console+0x28/0x354
[ 0.218768] [<ffff000008d0d840>] cdns_uart_console_init+0x14/0x20
[ 0.224923] [<ffff000008d0b6e4>] console_init+0x30/0x40
[ 0.230198] [<ffff000008cce8ac>] start_kernel+0x2e0/0x438
[ 0.235649] [<ffff0000080811c8>] 0xffff0000080811c8
我们以univ8250_console_init为例
static int __init univ8250_console_init(void)
{
if (nr_uarts == 0)
return -ENODEV;
serial8250_isa_init_ports();
register_console(&univ8250_console);
return 0;
}
console_initcall(univ8250_console_init);
原来就是在univ8250_console_init 中直接调用register_console,这个函数是所有console driver 必须调用的
其次通过console_initcall将自己也就是univ8250_console_init 添加到__con_initcall_start和__con_initcall_end 之间
可以看到console_initcall 是放在con_initcall.init 这个section中
#define console_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.con_initcall.init) = fn
而con_initcall.init 是让在__con_initcall_start和__con_initcall_end 之间的.
#define CON_INITCALL \
VMLINUX_SYMBOL(__con_initcall_start) = .; \
KEEP(*(.con_initcall.init)) \
VMLINUX_SYMBOL(__con_initcall_end) = .;
所以要注册自己的console的driver的话,可以通过console_initcall 将自己添加到__con_initcall_start和__con_initcall_end,这样kernel初始化的时候就会自动调用init函数.
0 0
- console_init
- console_init初始化的研究
- linux启动start_kernel之console_init
- kernel的console_init和printk
- linux2.6中的console_init初始化的研究
- pxa2128 linux kernel console_init 控制台初始化
- [Funkunux] Linux_2.6.22.6 内核start_kernel函数分析之console_init
- 窄带物联网(NB-IoT)基础知识
- 头上出汗 自汗盗汗
- JAVA 利用XML生成json完成接口对接实现
- 0.5px边框的实现
- layer.close()或者layer.closeAll()失效的情况下强制关闭layer弹窗的方法
- console_init
- Struts学习笔记一——servlet回顾及Struts引出
- AsyncTask的简单例子
- 在Linux下的进程资源的限制(struct rlimit)详解
- Notepad++配置python运行
- UI适配原理及通用解决方法实战
- XStream 实现 javabean 与 xml 互转
- POJ 1190 生日蛋糕(DFS+剪枝)
- CSS中border:none和border:0的区别