xloader bootlog access

1. xloader 中除了把log输出到串口外,还备份存放在 &__LOG_START --- &__LOG_END中

void puts(char *buf)
{               
        uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;

        while (*buf)
        {
                while (IsTxfifoFull());
                
                *logBuffer++ = *buf;
                //备份到SRAM中
                if (logBuffer >= &__LOG_END)
                        logBuffer = &__LOG_START;
                //输出到串口
                pUartRegs->DATA.Data = *buf++;
        }
        *logBuffer = 0;
}       
logbuffer 的定义与初始化:

static char *logBuffer;
uart_error_t UART_Init(uart_baudrate_t baudrate, uart_parity_bit_t parity_bit,
                uart_stop_bits_t stop_bits, uart_data_bits_t data_bits)
{
        /* Variable to flush Rx fifo */
        volatile uint32_t dataflushed;

        uart_register_t *pUartRegs = (uart_register_t *) UART1_REG_START_ADDR;
        gpio_register_t *pGpio0Regs = (gpio_register_t *) GPIO0_REG_START_ADDR;

        //logBuffer在 UART_Init()中初始化
        logBuffer = &__LOG_START;
        memset(logBuffer, 0, &__LOG_END - logBuffer);
__LOG_START 和 __LOG_END 在default.dld 链接文件中定义:

/* The sizes of the stacks used by the application. NOTE: you need to adjust */
//LOG buffer的大小
LOG_SIZE       = 2048;
        GROUP : {
                __LOG_START = .;
                . += LOG_SIZE;
                __LOG_END = .;
2. 内核中,把bootlog 通过/sys 接口导出来:

/*
 * =============================================================================
 *   Cartesio Bootloader Log Access
 * =============================================================================
 */

#ifdef CONFIG_SYSFS
static ssize_t bootlog_show(struct kobject *kobj, struct kobj_attribute *a, char *buf)
{
        //锁定地址
        const u32 __base = IO_ADDRESS(CARTESIO_ESRAM_BASE) + 0x3800;
        u32 *b32 = (u32 *)buf;
        int i;

        //读2048个字节
        for(i = 0; i < 2048; i += 4)
                *b32++ = readl(__base + i);

        return 2048;
}

//创建只读文件 bootlog
static struct kobj_attribute bootlog_attr = __ATTR_RO(bootlog);
 
static struct attribute *st_attrs[] = {
        &bootlog_attr.attr,
        NULL,
};

static struct attribute_group st_attr_group = {
        .attrs = st_attrs,
        //group 表示会建立出 stmicro 目录,里面会有 bootlog选项
        .name = "stmicro",
};
#endif /* CONFIG_SYSFS */
这里通过 sys_create_group(kernel_kobj, &st_attr_group) 导出:

sys_create_group(kernel_kobj, ) 会在 /sys/kernel/ 下建立出stmicro 目录,stmicro 目录想会有一个bootlog文件,是只读的.

static int __init cartesio_core_late_init(void)
{
        /*
         * Register core-specific platform devices depending on board devices
         */
        platform_add_devices(core_late_devices, ARRAY_SIZE(core_late_devices));

#ifdef CONFIG_SYSFS
        sysfs_create_group(kernel_kobj, &st_attr_group);
#endif

        return 0;
}
3. 用户空间读取bootlog:

int getlog()
{       
        char *log = harAPI_getLog();
        printf("x-loader logs :\n");
        
        while (*log)
        {
                printf("%s\n", log);
                log += strlen(log) + 1;
        }       
                
        return 0;
}
char *harAPI_getLog()
{       
        int fd;
        char logbuf[LOG_BUF_SIZE];
        char *buf;
        FILE *log;
                
        buf = logbuf;
        //打开bootlog文件
        log = fopen(BOOTLOG, "r");
        if(!log){
                printf("Open bootlog failed\n");
                return 0;
        }

        //读取文件到buf, 大小为2048
        if (fread(buf, LOG_BUF_SIZE, 1, log) != 1) {
                puts("Read bootlog failed");
        }
        
        fclose(log);
        return buf;
}  
#define LOG_BUF_SIZE     2048
#define BOOTLOG          "/sys/kernel/stmicro/bootlog"
这样就实现了bootloader log 从用户空间读取出来的功能。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值