Linux 부팅 로그에 다음과 같이 나타나는 UART가 있습니다.
AMDI0020:01: ttyS5 at MMIO 0xfedca000 (irq = 4, base_baud = 3000000) is a 16550A
이 UART 포트에 대해 Linux 커널 부팅 로깅을 활성화하고 싶습니다. 이를 위해 커널 부팅 매개변수를 추가합니다.
console=uart,mmio32,0xfedca000,115200n8
결과적으로 어떤 이유로 로그가 두 부분으로 분할됩니다(오실로스코프를 사용하여 확인하기도 했습니다).
- 시작 로그의 첫 번째 부분의 속도는 3000000입니다.
- 시작 로그의 두 번째 부분의 속도는 115200입니다.
아마도 분할은 ttyS5가 초기화될 때 바로 발생합니다.
나는 글쓰기가 전부라고 생각한다.
console=uart,mmio32,0xfedca000,115200n8
바꾸다
console=ttyS5,115200n8
실제 드라이버 초기화 전에 작동하는 UART를 얻는 것입니다.
하지만 어떤 이유에서인지 uart,mmio32,0xfedca000,115200n8
매개변수는 애초에 속도를 설정하지 않습니다.
초기 커널 부팅 로그를 위해 직렬 속도를 MMIO UART로 설정할 수 있습니까?
내 OS가 다음과 같은 경우를 대비해
~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic
~$ uname -a
Linux ermak-Diesel 5.4.0-65-generic #73~18.04.1-Ubuntu SMP Tue Jan 19 09:02:24 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
답변1
제 경우에는 비표준 UART 시계로 인해 문제가 발생했습니다.
earlycon
드라이버는 UART 클록을 이 값으로 설정합니다.BASE_BAUD * 16
static int __init register_earlycon(char *buf, const struct earlycon_id *match)
{
...
port->uartclk = BASE_BAUD * 16;
...
}
x86의 경우 아치가 BASE_BAUD
파일에 정의되어 있습니다.https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/serial.h
/*
* This assumes you have a 1.8432 MHz clock for your UART.
*
* It'd be nice if someone built a serial card with a 24.576 MHz
* clock, since the 16550A is capable of handling a top speed of 1.5
* megabits/second; but this requires a faster clock.
*/
#define BASE_BAUD (1843200/16)
하지만 제 경우에는 AMDI0020
UART가 표준 1.8432MHz 클럭을 사용하지 않고 48MHz 클럭을 사용합니다.
이것이 base_baud = 3000000
인쇄가 표준 115200에 위배되는 이유입니다.
1 843 200 / 16 = 115 200
48 000 000 / 16 = 3 000 000
AMDI0020:01: ttyS5 at MMIO 0xfedca000 (irq = 4, base_baud = 3000000) is a 16550A
드라이버에서 다른 시계를 설정할 가능성이 없습니다. 하지만 다른 느린 전송 속도를 설정하여 속일 수 있습니다.
115 200 * (1 843 200 / 48 000 000) = 4 423,68
이 설정은 초기 부팅 단계에서 올바른 출력을 제공했습니다.
console=uart,mmio32,0xfedca000,4423
하지만 이 접근 방식은 이상적이지 않습니다. 잘못된 전송 속도로 인해 후속 커널 부팅 단계가 올바르게 인쇄되지 않기 때문입니다( AMDI0020
드라이버가 인계되면(https://github.com/torvalds/linux/blob/master/drivers/tty/serial/8250/8250_dw.c)).
BIOS/GRUB 단계에서 UART가 올바른 속도로 설정된 경우 전송 속도 설정을 생략할 수 있습니다.
console=uart,mmio32,0xfedca000
이렇게 하면 모든 커널 로그가 올바르게 인쇄됩니다.
그러나 올바른 해결책은 물론 earlycon
드라이버에 필요한 지원을 추가하는 것입니다.
현재 AMDI0020
이 드라이버에서 시계를 가져오는 중:https://github.com/torvalds/linux/blob/master/drivers/acpi/acpi_apd.c
static const struct apd_device_desc cz_uart_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 48000000,
.properties = uart_properties,
};
...
static const struct acpi_device_id acpi_apd_device_ids[] = {
...
{ "AMDI0020", APD_ADDR(cz_uart_desc) },
...
}
ACPI가 구문 분석되기 전에 설정 되므로 earlycon
문제를 해결하는 유일한 방법은 다음과 같이 콘솔에 대한 사용자 정의 시계를 전달할 가능성을 추가하는 것 같습니다.
console=uart,mmio32,0xfedca000,115200,48000000