Skip to content

UART / TTY End-to-End Flow (Day29 + Day30 Summary)

🎯 Objective

  • Provide a complete picture of UART communication in Linux
  • Connect user-space APIs to kernel driver execution
  • Summarize TX / RX flow, buffering, and design principles
  • Serve as a quick reference for debugging and interviews

🧠 1. System Overview

USER SPACE
  write() / read()
TTY core
Line Discipline (N_TTY)
Serial Core (uart_ops)
PL011 Driver
UART Hardware (FIFO)
GPIO / Wire

🟢 2. TX Flow (User → Hardware)

Full Path

write()
  → tty_write()
  → line discipline
  → uart_write()
  → xmit buffer
  → pl011_start_tx()
  → UART TX FIFO
  → wire

Step-by-Step

1. write()

  • user initiates transmission
  • returns quickly after buffering

2. xmit buffer

port->state->xmit
  • circular buffer (~4KB)
  • decouples user speed from hardware speed

3. pl011_start_tx()

  • moves data from xmit buffer → UART FIFO
  • may enable TX interrupt for remaining data

Key Insight

write() ≠ data transmitted
write() = data buffered


🔵 3. RX Flow (Hardware → User)

Full Path

wire
  → UART RX FIFO
  → interrupt
  → pl011_irq()
  → flip buffer
  → tty buffer
  → read()

Step-by-Step

1. UART RX

  • hardware receives data into FIFO

2. Interrupt

  • triggered when FIFO reaches threshold

3. pl011_irq()

  • reads FIFO
  • pushes data to flip buffer

4. Flip Buffer

tty_insert_flip_string()
tty_flip_buffer_push()
  • temporary kernel buffer
  • separates IRQ from user space

5. TTY buffer

  • managed by TTY core
  • final buffer before user read()

6. read()

  • copies data from TTY buffer to user

Key Insight

read() ≠ direct hardware access
read() = data from TTY buffer


🔁 4. TX vs RX Comparison

Aspect TX RX
Entry write() interrupt
Buffer xmit buffer flip buffer
Driver role push data collect data
Direction user → hardware hardware → user
Timing async interrupt-driven

🧠 5. Buffer Architecture

TX:
user → tty buffer → xmit buffer → FIFO

RX:
FIFO → flip buffer → tty buffer → user

Buffer Roles

Buffer Purpose
FIFO hardware staging
xmit buffer TX decoupling
flip buffer IRQ-safe staging
tty buffer user-visible data

🧠 6. Why So Many Buffers?

1. Interrupt Safety

  • cannot access user memory in IRQ
  • must copy to kernel buffer

2. Decoupling

driver ≠ user space
  • independent timing
  • independent execution context

3. Performance

  • batching reduces interrupts
  • asynchronous transmission

4. Reliability

  • prevents data loss
  • absorbs burst traffic

🧠 7. TTY vs Simple Driver

Simple Char Driver

user → driver → hardware
user ← driver ← hardware

TTY Subsystem

user → tty → driver → hardware
user ← tty ← driver ← hardware

Key Difference

TTY introduces abstraction, flexibility, and reusability


🧠 8. Role Separation

Layer Responsibility
User read/write
TTY core buffering, fd management
Line discipline behavior (raw/canonical)
Serial core generic UART handling
Driver hardware interaction
Hardware physical transmission

🧠 9. Design Principles

1. Asynchronous I/O

  • write() does not block transmission
  • driver sends data in background

2. Layered Design

  • separation of concerns
  • reusable components

3. Interrupt-driven RX

  • efficient data reception
  • minimal CPU usage

4. Buffer-based Flow Control

  • handles speed mismatch
  • prevents overflow

🎯 10. Key Takeaways

  • UART is hardware, TTY is abstraction
  • write() pushes data into buffer
  • read() pulls data from buffer
  • flip buffer bridges IRQ and TTY core
  • driver does not interact with user directly

🚀 Final Insight

Linux TTY subsystem transforms a simple UART into a flexible, asynchronous, and reusable communication interface