U-Boot find_cmd 함수 동작 원리와 명령어 검색 메커니즘

명령어 테이블 구조체

U-Boot에서 각 명령어는 cmd_tbl_s 구조체로 표현되며, 명령어 이름, 인자 개수, 실행 함수, 도움말 등을 포함한다.

struct cmd_tbl_s {
    char    *cmd_name;      /* 명령어 이름 */
    int     arg_max;        /* 최대 인자 수 */
    int     auto_repeat;    /* 자동 반복 가능 여부 */
    int     (*exec)(struct cmd_tbl_s *, int, int, char *[]);
    char    *brief;         /* 간단한 사용법 */
#ifdef  CFG_LONGHELP
    char    *detail;        /* 상세 도움 */
#endif
#ifdef CONFIG_AUTO_COMPLETE
    int     (*complete)(int, char *[], char, int, char *[]);
#endif
};

typedef struct cmd_tbl_s cmd_tbl_t;

전용 섹션을 통한 명령어 배치

컴파일러 속성을 활용해 명령어 정보를 .u_boot_cmd 섹션에 배치한다. 이를 통해 타임에 연속된 메모리 영역에서 명령어를 순회할 수 있다.

#define SECTION_ATTR __attribute__((unused, section(".u_boot_cmd")))

#define SHELL_CMD(n, args, repeat, fn, usage_str, help_str) \
    cmd_tbl_t __cmd_info_##n SECTION_ATTR = { \
        #n, args, repeat, fn, usage_str, help_str \
    }

매크로 전개 결과는 다음과 같다. __cmd_info_hello 변수가 지정된 섹션에 배치되며, 초기값으로 명령어 정보가 설정된다.

/* SHELL_CMD(hello, 3, 1, run_hello, "help", "detail") 전개 후 */
cmd_tbl_t __cmd_info_hello
__attribute__((unused, section(".u_boot_cmd"))) = {
    "hello", 3, 1, run_hello, "help", "detail"
};

find_cmd 함수 분석

입력된 문자열과 일치하는 명령어를 검색하며, 전체 일치뿐 아니라 고유한 축약형도 허용한다. 점(.) 이전까지만 비교하여 cp.b 같은 형태도 처리한다.

cmd_tbl_t *find_cmd(const char *input)
{
    cmd_tbl_t *entry;
    cmd_tbl_t *candidate = &__cmd_table_begin;
    const char *dot_pos;
    int match_len;
    int partial_cnt = 0;

    /* 점(.) 이전 길이 계산: "cp.b" -> "cp" 길이 */
    dot_pos = strchr(input, '.');
    match_len = dot_pos ? (dot_pos - input) : strlen(input);

    for (entry = &__cmd_table_begin;
         entry != &__cmd_table_end;
         entry++) {
        
        if (strncmp(input, entry->cmd_name, match_len) != 0)
            continue;

        if (match_len == strlen(entry->cmd_name))
            return entry;           /* 완전 일치 */

        candidate = entry;          /* 축약 가능 후보 */
        partial_cnt++;
    }

    /* 후보가 유일하면 축약 명령어로 인정 */
    if (partial_cnt == 1)
        return candidate;

    return NULL;                    /* 미발견 또는 모호한 축약 */
}

검색 알고리즘 핵심

링커 스크립트에서 __cmd_table_begin__cmd_table_end 볼로 섹션 경계를 정의한다. 이를 통해 for 루프가 연속된 명령어 테이블을 순회하며, O(n) 선형 검색으로 입력 명령어와 매칭시킨다.

축약 처리 로직의 핵심은 partial_cnt 카운트다. ststartstop 두 명령어에 모두 매칭되면 모호성으로 판단해 NULL을 반환한다. 반면 hehello만 매칭되면 유일 후보로 인정되어 실행 가능하다.

태그: U-Boot embedded systems Linker Script Memory Section Command Parser

6월 7일 21:48에 게시됨