1 Linux aarch64-linux-gnu-gcc
1.1 aarch64-linux-gnu-gcc
https://releases.linaro.org/components/toolchain/binaries
gcc-linaro-*.tar.xz: compiler
sysroot-linaro-*.tar.xz: root fs

xz -d xxx.tar.xz
tar xvf xxx.tar

Support legacy arm-linux-gcc binary:
Userspace binary formats - > Kernel support for 32-bit EL0

1.2 Linux libtool静态链接
libtool在link-mode时,可以使用参数:-all-static
且这个参数要放在ld之后,如下:
/bin/sh ../libtool --tag=CC \
--mode=link aarch64-linux-gnu-gcc \
-all-static 

在这里是放在aarch64-linux-gnu-gcc之后,不然提示找不到-all-static。
生成的链接命令会自动加上:-static,并且自动寻找lib*.a的静态库。

1.3 showcase
# CROSS_COMPILE = \
# /path/to/bin/aarch64-linux-gnu-

# CC means C Compiler
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld

.PHONY: clean

OBJS = src/main.o

CFLAGS = \
    -I./include

LDFLAGS =

# compile every c file to object
%.o: %.c
        $(CC) $(CFLAGS) -c $^ -o $@
# link all of the objects to uevent_mon
uevent_mon: $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) \
            -o $@

clean:
        rm -rf $(OBJS)
        rm -rf uevent_mon

2 Android.mk文件
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

SRC_LIST := $(wildcard $(LOCAL_PATH)/*.c)
LOCAL_SRC_FILES := \
    $(SRC_LIST:$(LOCAL_PATH)/%=%)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_LDLIBS := -llog
LOCAL_MODULE := uevent_mon

#LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := optional
$(warning #$(SRC_LIST)#)

include $(BUILD_EXECUTABLE)

Android工具链独立编译二进制,需要给aarch64-linux-android-gcc提供sysroot目录,否则无法编译。

3 源代码
// uevent DEVPATH for HiCar
#define LOG_TAG "uevent_mon"

#include <ctype.h>
#include <linux/netlink.h>
#include <poll.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>

#define UEVENT_PARAMS_MAX 512
#define BUFF_LEN  (16*1024)
#define OUT_FILE "/dev/uevent.log"

static int g_dwFd = -1;
static int time_arg = 1;
static char proc_name[64] = {'\0'};
static char out_file[128] = {'\0'};

static void write_log(const char **fmt,...)
{
    va_list arg;
    FILE *fp = NULL;

    fp = fopen(out_file, "a+");
    if (fp == NULL) {
        return ;
    }

    va_start(arg,fmt);
    vfprintf(fp,fmt,arg);
    va_end(arg);

    fclose(fp);
}

static int my_printf(const char *fmt, ...)
{
    char line[512];
    va_list arg;
    int rc = 0;

    va_start(arg, fmt);
    rc = vsnprintf(line, 511, fmt, arg);
    if (rc > 0) {
        line[rc] = '\0';
    }
    va_end(arg);

    printf(line);

    return rc;
}

static void print_usage(char *toast)
{
    const char *usage =
    "Usage: %s [OPTION...]\n"
    "    -f, --file    saved log path, "
    "</data/uevent.log> by default\n"
    "    -h, --help    print the usage\n\n"
    "HOW-TO:\n"
    "copy this command to /vendor/bin/, "
    "which is for catching the kernel "
    "uevent logs\n\n"
    "For example:\n"
    "    %s -f /sdcard/uevent.log &\n"
    "    %s &\n\n";

    if (toast) {
        my_printf(toast, proc_name);
    }
    my_printf(usage,
        proc_name,
        proc_name,
        proc_name);
}

static void PrintUeventToolVersion(void)
{
    write_log(
    "\nInitial Uevent Tools Version:Beta v1.0\n");
    write_log("Author: George Tso\n");
}

static int UeventInit()
{
    struct sockaddr_nl addr;
    int sz = 64*1024;
    int s;

    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_pid = getpid();
    addr.nl_groups = 0xffffffff;

    s = socket(PF_NETLINK,
        SOCK_DGRAM,
        NETLINK_KOBJECT_UEVENT);
    if (s < 0) {
        return 0;
    }

    setsockopt(s,
        SOL_SOCKET,
        SO_RCVBUFFORCE,
        &sz, sizeof(sz));

    if (bind(s,
        (struct sockaddr *) &addr,
        sizeof(addr)) < 0) {
        close(s);
        return 0;
    }

    g_dwFd= s;
    return (g_dwFd > 0);
}

static int UeventNextEvent(char* buffer,
    int buffer_length)
{
    while (1) {
        struct pollfd fds;
        int nr;

        fds.fd = g_dwFd;
        fds.events = POLLIN;
        fds.revents = 0;
        nr = poll(&fds, 1, -1);

        if (nr > 0 && fds.revents == POLLIN) {
            int count = recv(g_dwFd,
                buffer, buffer_length, 0);
            if (count > 0) {
                return count;
            }
        }
    }

    return 0;
}

static void process_uevent(void)
{
    char *szBuff = (char *)malloc(BUFF_LEN);
    char *s = szBuff;
    char *szEnd = NULL;
    int dwActualLen = 0;
    char timeBuf[32];
    struct timeval tv;
    struct tm* ptm;

    memset(szBuff, 0, BUFF_LEN);

    PrintUeventToolVersion();
    my_printf("\nout file: %s\n", out_file);

    UeventInit();

    for (;;) {
        dwActualLen = UeventNextEvent(szBuff,
            BUFF_LEN - 1);
        s = szBuff;
        szEnd = s + dwActualLen;

        while (s < szEnd) {
            if (!isspace(*s)) {
                if (time_arg) {
                    gettimeofday(&tv, NULL);
                    ptm = localtime(&(tv.tv_sec));
                    strftime(timeBuf, 31,
                        "%Y-%m-%d %H:%M:%S",
                        ptm);
                    write_log(
                    "[%lu.%06lu] [%s.%06lu usec] %s\n",
                        tv.tv_sec, tv.tv_usec,
                        timeBuf, tv.tv_usec, s);
                } else {
                        write_log("%s\n", s);
                }
            } // end of  if (!isspace(*s))
            s += strlen(s) + 1;
        } // end of while
    } // end of for
}

static void parse_args(int argc, char **argv)
{
    char *p = NULL;

    if ((p = strrchr(argv[0], '/')) != NULL) {
        p++;
        strcpy(proc_name, p);
    } else {
        strcpy(proc_name, argv[0]);
    }

    argc--;
    argv++;

    while (argc > 0){
        if (!strcasecmp(argv[0], "-h") ||
           !strcasecmp(argv[0], "--help")) {
            print_usage(NULL);
            argc--;
            argv++;
            exit(0);
        } else if (!strcasecmp(argv[0], "-f") ||
           !strcasecmp(argv[0], "--file")) {
            argc--;
            argv++;
            if (argc == 0) {
                print_usage("Need argument\n");
                exit(0);
            }
            strcpy(out_file, argv[0]);
            argc--;
            argv++;
        } else {
            argc--;
            argv++;
        }
    }
}

//-----------------------------------------------------------------------------------
int main(int argc, char **argv)
{
    strcpy(out_file, OUT_FILE);
    parse_args(argc, argv);
    process_uevent();

    return 0;
}

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:22 天前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐