在内核解压缩之前,没有任何串口驱动加载。如何打印出了
Uncompressing Linux………………………………..
…………………….. done, booting the kernel.
https://geekwentfreak-raviteja.rhcloud.com/blog/2010/11/07/putc-putstr-how-linux-prints-to-uart-before-uncompressing-itself/
这里有一些参考资料。
我编译的树莓派内核,通过uboot 跟踪调试发现的确已经执行了这一句putstr。但是串口居然没有看到打印。
(后续事实证明是我之前的.config文件配置错了。)
找到putc的代码在
/arch/arm/mach-versatile/include/mach/uncompress.h
是直接操作串口寄存器来实现的。
static inline void putc(int c)
{
while (AMBA_UART_FR & (1 << 5))
barrier();
AMBA_UART_DR = c;
}
static inline void flush(void)
{
while (AMBA_UART_FR & (1 << 3))
barrier();
}
这里关键用了 AMBA_UART_FR AMBA_UART_DR这两个地址
定义是
#define AMBA_UART_DR (*(volatile unsigned char *)0x101F1000)
#define AMBA_UART_LCRH (*(volatile unsigned char *)0x101F102C)
#define AMBA_UART_CR (*(volatile unsigned char *)0x101F1030)
#define AMBA_UART_FR (*(volatile unsigned char *)0x101F1018)
这里应该根据不同的板子是不同的。
我查找了树莓派的BCM2835手册。在13章节里面 13.4 Register View里面有
The PL011 USRT is mapped on base adderss 0x7E20100. It has the following memorymapped registers.
这里描述的地址少写了一个0 应该是说uart的虚拟地址基地址是0x7e201000。对应于物理地址就是0x20201000
DR是DATA Register的缩写。FR是FLAG register的缩写。这里就用了这两个。看13.4的uart章节的uart address map
DR偏移是0
FR偏移是0x18
所以修改为
#define RPI_BASE_UART_REGISTER (0x20000000+0x201000)
#define RPI_UART_FR (*(unsigned char *)(RPI_BASE_UART_REGISTER + 0x18))
#define RPI_UART_DR (*(unsigned char *)(RPI_BASE_UART_REGISTER + 0x00))
/*
* This does not append a newline
*/
#define RPI_BUILD 1
static inline void putc(int c)
{
#ifdef RPI_BUILD
while (RPI_UART_FR & (1 << 5))
barrier();
RPI_UART_DR = c;
#else
while (AMBA_UART_FR & (1 << 5))
barrier();
AMBA_UART_DR = c;
#endif
}
static inline void flush(void)
{
#ifdef RPI_BUILD
while (RPI_UART_FR & (1 << 3))
barrier();
#else
while (AMBA_UART_FR & (1 << 3))
barrier();
#endif
}
这样就可以打印了
原来的AMBA_UART_DR AMBA_UART_FR就是基址不同,偏移还是对的。不知道是不是默认UART的偏移都是这样的。
其他的寄存器暂时我也没去了解。这里修改了基址操作对的寄存器就能够打印了。
本文介绍如何在树莓派内核解压缩前通过串口进行打印输出。通过修改UART寄存器地址,实现了内核启动过程中的串口调试信息显示。

4532

被折叠的 条评论
为什么被折叠?



