Android 系统(250)---main log导入到uart口

main log导入到uart口

 

不开机问题调试起来比较麻烦,可能是底层出错,比如KE、preloader崩溃,lk崩溃,也可能是上层崩溃。

如果是上层崩溃,需要抓main log,抓log步骤如下:

1. 先检查adb shell是否可用,如果可用可以用adb shell "logcat -v time -b main -b system > logcat.txt"

2. 如果不能用,则要开uart console,具体请参考:FAQ03891

3. 如果uart console也不能用,那么只能在上层代码里让main log直接导入到uart口了。下面提供方法。

 

[SOLUTION]

1. 在system/core/liblog/logd_write.c添加代码到__write_to_log_daemon(),将main log导入到kernel buffer:

static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
{
    ......
    if (!nr) {
        return -EINVAL;
    }
#if 1 /* add this block */
    if (log_id == LOG_ID_MAIN || log_id == LOG_ID_SYSTEM) {
        static const char* name = "/dev/__kmsg__";
        static int klog_fd = -1;

        if (klog_fd < 0) {
            klog_fd = open("/dev/kmsg", O_WRONLY|O_CLOEXEC);
            if (klog_fd < 0 && mknod(name, S_IFCHR | 0600, (1 << 8) | 11) == 0) {
                klog_fd = open(name, O_WRONLY|O_CLOEXEC);
                unlink(name);
            }
        }
        if (klog_fd >= 0 && *(unsigned char *)vec[0].iov_base >= ANDROID_LOG_WARN) {
            char c = '?', str[5 + vec[1].iov_len + vec[2].iov_len];
            long rt;
 
            switch (*(unsigned char *)vec[0].iov_base) {
            case ANDROID_LOG_WARN: c = 'W'; break;
            case ANDROID_LOG_ERROR: c = 'E'; break;
            case ANDROID_LOG_FATAL: c = 'F'; break;
            case ANDROID_LOG_SILENT: c = 'S'; break;
            default: break;
            }
            rt = snprintf(str, sizeof(str) - 1, "%c %s %s\n", c, (char *)vec[1].iov_base, (char *)vec[2].iov_base);
            if (rt > 0)
                TEMP_FAILURE_RETRY(write(klog_fd, str, rt));
        }
    }
#endif
    ......
}

 

2. 修改kernel/drivers/char/mem.c里的

[11] = { "kmsg", 0644, &kmsg_fops, NULL },

修改为:

[11] = { "kmsg", 0666, &kmsg_fops, NULL },


3. 在external/sepolicy/domain.te添加:

allow domain kmsg_device:chr_file rw_file_perms;

 

4. 在external/sepolicy/device.te修改:

type kmsg_device, dev_type;

修改为:

type kmsg_device, dev_type, mlstrustedobject;


5. 全编译:
make -j24

 

6. 抓到的uart log大致如下:

[14:46:02.401] [ 22.618857] .(1)[388:mediaserver][name:ccci&][ccci1/chr]MD state 2, 3
[14:46:02.401] [ 22.619350] .(2)[787:CCCIReadThread]W SpeechMessengerECCCI ..[MD Reset Notify(MSG_M2A_EM_DATA_REQUEST: 0xaf700000)]..
[14:46:02.401] [ 22.622637] E SpeechMessengerECCCI SendMsgFailErrorHandling(), message: 0x2f760000
[14:46:02.429] [ 22.624168] W SpeechMessengerECCCI SendMsgFailErrorHandling(), message: 0x2f760000, ack don't care

 

7. 注意:O版本后还需下面的修改

为所有进程添加mknodat的权限

 /external/minijail/util.c

45#elif defined(__arm__)
46#if defined(__ANDROID__)
47const char *log_syscalls[] = {"clock_gettime", "connect", "fcntl64", "socket",
48 "writev"};
49#else
50const char *log_syscalls[] = {"connect", "gettimeofday", "send"};
51#endif
52#elif defined(__aarch64__)
53#if defined(__ANDROID__)
54const char *log_syscalls[] = {"connect", "fcntl", "sendto", "socket", "writev"};
55#else
56const char *log_syscalls[] = {"connect", "send"};

修改为

 

45#elif defined(__arm__)
46#if defined(__ANDROID__)
47const char *log_syscalls[] = {"clock_gettime", "connect", "fcntl64", "socket",
48 "writev","mknodat"};
49#else
50const char *log_syscalls[] = {"connect", "gettimeofday", "send"};
51#endif
52#elif defined(__aarch64__)
53#if defined(__ANDROID__)
54const char *log_syscalls[] = {"connect", "fcntl", "sendto", "socket", "writev","mknodat"};
55#else
56const char *log_syscalls[] = {"connect", "send"};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值