Linux tty驱动学习 - UART驱动注册

本文详细介绍了Linux系统中UART驱动的注册过程,包括uart_register_driver()的使用,如何分配和初始化uart_state,以及如何通过tty_register_driver()注册tty驱动。同时讲解了platform_device_alloc()创建并添加platform device,以及serial8250_register_ports()如何注册8250串口设备,重点在于硬件初始化和tty设备注册。最后阐述了如何通过serial8250_find_match_or_unused()寻找并替换合适的uart_port,确保设备正确工作。
摘要由CSDN通过智能技术生成
8250/16550系列芯片为常见的UART芯片,该类芯片的驱动文件为8250.c,位于内核源码的/drivers/serial/目录下面。serial8250_init为该驱动的入口函数,nr_uarts和UART_NR在内核配置中定义,跟具体的平台相关,通常定义为4。由于CONFIG_SPARC没有被定义,所以做的第一件事情就是注册一个名为serial_8250_reg的UART驱动。
static int __init serial8250_init(void)
{
	int ret;

	if (nr_uarts > UART_NR)
		nr_uarts = UART_NR;

	printk(KERN_INFO "Serial: 8250/16550 driver, "
		"%d ports, IRQ sharing %sabled\n", nr_uarts,
		share_irqs ? "en" : "dis");

#ifdef CONFIG_SPARC
	ret = sunserial_register_minors(&serial8250_reg, UART_NR);
#else
	serial8250_reg.nr = UART_NR;
	ret = uart_register_driver(&serial8250_reg);
#endif
	if (ret)
		goto out;

	serial8250_isa_devs = platform_device_alloc("serial8250",PLAT8250_DEV_LEGACY);
	if (!serial8250_isa_devs) {
		ret = -ENOMEM;
		goto unreg_uart_drv;
	}

	ret = platform_device_add(serial8250_isa_devs);
	if (ret)
		goto put_dev;

	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);

	ret = platform_driver_register(&serial8250_isa_driver);
	if (ret == 0)
		goto out;

	platform_device_del(serial8250_isa_devs);
put_dev:
	platform_device_put(serial8250_isa_devs);
unreg_uart_drv:
#ifdef CONFIG_SPARC
	sunserial_unregister_minors(&serial8250_reg, UART_NR);
#else
	uart_unregister_driver(&serial8250_reg);
#endif
out:
	return ret;
}

uart_register_driver(struct uart_driver *drv)向uart核心层注册一个uart驱动。在uart驱动中,用uart_state来表示一个uart设备。所以首先为drv->state分配内存空间,驱动支持drv->nr个设备,就分配对应个数的内存空间。接着调用alloc_tty_dirver()申请一个tty_driver,该函数会先分配tty_driver的内存空间,然后做简单的初始化。tty_driver大部分的初始化工作在该函数之后完成,利用uart_driver的信息初始化tty_driver,比如驱动和设备的名字,以及主次设备号的值,最重要的是会绑定uart_driver和tty_driver之间的链接关系。在ldd3的tty驱动中有提到tty_driver中的重要成员tty_operations,所以调用tty_set_operations()把uart_ops赋值给tty_driver的tty_operations变量。在uart驱动层这边,用uart_state和uart_port来表示具体的设备,所以最后是对uart_state进行初始化,而且主要是对里面的tty_port进行初始化操作。uart驱动注册的最后就是调用tty_register_dirver()注册tty驱动,从注册过程可以看出uart驱动是作为tty的驱动的成员被注册到tty核心层,用户空间通过系统调用是先跟tty核心沟通,往下层就是tty驱动,最后是通过tty_driver的成员driver_state找到最终的uart驱动。

	/*
	 * Maybe we should be using a slab cache for this, especially if
	 * we have a large number of
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值