串口 (三) linux串口

# uname -r
2.6.22.6-g8701f843-dirty
# cat /proc/cmdline 
noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
✗ find . -name "*.o"
./s3c2410.o // CONFIG_SERIAL_S3C2410
./built-in.o
./serial_core.o // CONFIG_SERIAL_CORE

综述


linux的串口中有几个概念,一个就是文件 /dev/ttyXXX ,一个就是控制台 ,一个就是  early console
0. 串口的寄存器操作
- 收
s3c24xx_serial_rx_chars
	rd_regb(port, S3C2410_URXH);

-static void                                                                          
s3c24xx_serial_console_putchar(struct uart_port *port, int ch)                       
{                                                                                    
    unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);                          
    while (!s3c24xx_serial_console_txrdy(port, ufcon))                               
        barrier();                                                                   
    wr_regb(cons_uart, S3C2410_UTXH, ch);                                            
}
1. 串口设备文件
1.
各种串口设备形成的设备节点/dev/ttyXXX(例如 ttyAMA0,不指代所有的tty*文件) 是串口驱动 通过  uart_register_driver 和 uart_add_one_port 形成的,其中利用了tty子系统和serial子系统.

2.控制台

2.
在 控制台概念中, bootargs 中 要传入 console=aaa console=bbb console=ccc ...(也可能只有console =aaa) , 那么如果 aaa bbb ccc 驱动中有对应的 console 被注册,就是将 printk 的内容打印到 aaa bbb ccc 上,对于上述例子,ccc(最后一个)为交互控制台,其他仅为打印控制台.
在 驱动中,是 用的 console_initcall(s3c24xx_serial_initconsole); 这样子来注册控制台.注册的函数存在于 __con_initcall_start 和 __con_initcall_end 中.

c0021890 T __con_initcall_start                                                  
c0021890 t __initcall_kgdb_console_init   // CONFIG_KGDB_CONSOLE                         
c0021894 t __initcall_con_init    // 一定会有的                                        
c0021898 t __initcall_s3c24xx_serial_initconsole   //   CONFIG_SERIAL_S3C2410_CONSOLE     
c002189c T __con_initcall_end

__con_initcall_start 和 __con_initcall_end 中 的函数 在console_init 的时候被调用. 
这些函数都调用 register_console 来注册控制台(匹配到 console=xxx 的才能注册成功)
3. early console
3.
早期linux版本(例如linux-2.6.22.6)中 arm架构是没有 early console 的概念的.后来就有了.且发展为两个版本.
early console 作为一种调试手段,在 early_console 注册之后,console_init之前可以利用printk打印到串口上进行调试
early console 仅作为 console_init 之前使用, console_init 之后early console 就被 disabled.
early console 仅实现了发送,没有实现初始化和接收,初始化已经在 bootloader做过.

版本1: early printk 				early_param("earlyprintk", setup_early_printk);
版本2: 版本1的升级版: earlycon 		early_param("earlycon", setup_of_earlycon);

	3.1 early printk
		def_config
            CONFIG_EARLY_PRINTK
            CONFIG_DEBUG_LL // 平台相关
        dts
        	chosen{
                bootargs ="earlyprintk";
            };
		code
			1. 平台无关代码
				arch/arm/kernel/early_printk.c
				early_param("earlyprintk", setup_early_printk); // 在 parse_args "early options" 解析
					early_write
						printch // 平台相关
			2. 平台相关代码
				arch/arm/kernel/debug.S
                    ENTRY(printch)                  
                            addruart_current r3, r1, r2
                            mov r1, r0                 
                            mov r0, #0                 
                            b   1b                     
                    ENDPROC(printch)
	3.2 earlycon
    	def_config
    		CONFIG_SERIAL_EARLYCON
    		CONFIG_OF_EARLY_FLATTREE
    		CONFIG_SERIAL_SAMSUNG_CONSOLE // 平台相关
		dts
            chosen{
                bootargs = "earlycon";
                linux,stdout-path = &uart0;   
            };

            uart0: serial@e2900000 { // 对于earlycon而言,只在乎compatible属性和reg属性,其他需要初始化的都要在uboot中完成。 
                compatible = "samsung,s5pv210-uart";
                reg = <0xe2900000 0x400>;
            };
		code
			1. 平台无关
				early_param("earlycon", setup_of_earlycon); // 在 parse_args "early options" 解析
					// 根据 linux,stdout-path = &uart0; 中的 compatible 匹配 OF_EARLYCON_DECLARE 中 的 字符串,然后拿到 s5pv210_early_console_setup 函数
					of_setup_earlycon
						register_console(early_console_dev.con);
			2. 平台相关
				OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart",
            s5pv210_early_console_setup);
				s5pv210_early_console_setup
					samsung_early_console_setup
						device->con->write = samsung_early_write;

    

其他

如果一个串口设备要作为控制台的话,也就是启动信息输出到改串口的话,一定要在串口驱动中 添加 注册 register_console 的代码, 且在 bootargs 中一定要 添加 console=xxx0,xxx 为 register_console中的参数的name成员
内核的串口驱动比较简单,但是在串口驱动之上,封装了很多逻辑.
但是从上层到 printch(操作寄存器的函数) ,这个过程中, 夹杂了很多其他杂七杂八的逻辑

tty子系统
vt
pty
hvc

console
gdb console
dmesg
printk

也就是说 tty console 不只是为 串口驱动准备的,而是 tty console 做一个 生产者, 供给了很多消费者,而串口驱动只是其中一个.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值