임베디드 개발자들의 성격

2009년 스마트폰 시대 부터 비에스피(BSP: Embedded Linux driver/Linux kernel)개발을 시작한 지 어언 9년이 흘렀다. 정말 9년 동안 수 많은 이슈를 만났고 이 놈들을 해결하면서 정말 고생도 많이 했다. 그런데 9년의 시간이 흐른 시점에서 한 가지 아쉬운 점은 나의 체험으로 느낀 점을 글로 남기지 못했다. 사실 그 당시 몸도 가누기 힘들 정도로 체력이 방전되어 어떤 글을 남긴다는 것은 상상도 하지 못했다. 이제 조금 나를 뒤돌아 볼 시점인 것 같다. 사실 요즘 조금 한가하기도 하다.

사실 난 원래 풤에어 혹은 비에스피(firmware, BSP)출신 개발자가 아니다. 난 2005년부터 휴대폰을 개발을 했는데 당시 피쳐폰(feature phone)의 유아이 혹은 미들웨어 유지 보수을 담당했었다. 구체적으로 벡터 폰트, 플레시 라이트 등등을 유아이 플렛폼에 맞게 포팅을 했다. 포팅한 함수들을 묶어서 SMS, Call, Camera 등등과 같은 어플리케이션(application) 담당자들에게 API를 제공했다. 이후 에디터 및 플레시 플러그인 까지 개발을 했었다.

그 당시 가끔 펌웨어 개발자(지금 임베디드, BSP개발자)들과 함께 논의를 하면서 디버깅을 할 일이 종종 있었다. 그런데 내 기억 속에서 펌웨어 개발자들은 성질이 참 더러웠다. 상당히 까칠하고 대화가 잘 되지 않는 놈들이었다.

그런데 지금 동료들의 99%는 임베디드 소프트웨어 개발자들이다. 9년 전 내가 생각했던 까칠하고 대화가 잘 안 되는 놈이라고 기억했던 놈들이 나와 내 동료들인 것이다.

우선 기술적인 내용을 적기 앞서 임베디드 개발자들에 인간적인 면 - 성격, 특징 등등-에 대해서 느낀 점에 대해서 할 말이 참 많다.

사실 난 요즘에도 직장 동료들(임베디드 개발자들)과 대화를 나눌 때 정말 답답하다. 이 녀석들은 차를 마시거나 술을 마실 때에도 대부분 기술적인 어떤 사실, 내용 및 생각에 대해서 말하기를 정말 좋아한다. 가끔 보면 상대방이 자신이 말을 듣고 어떤 반응을 보이는 지 개의치 않는 놈들도 볼 수 있다. 정말로 로보트가 갱스터 랩을 하는 것 같이 느낄 때가 많다.
 
가령 아래와 같은 소리를 40분 동안 숨도 쉬지 않고 열정적으로 말 하는 것이다.
"어제 코어덤프에서 스팩 오버플로우(stack overflow) 흔적을 본 것 같은데 프레임 포인터(frame pointer) 주소 근처의 덤프의 패턴이 일정하지 않는 것 같더라구. 그런데 스택이 깨져도 바로 커널 패닉이 발생하지는 않잖어? 스택이 깨질 때의 정확한 순간을 포착 해야 하는데 이를 위한 스팩 프로파일러란 패치가 있더라고. run queue에 쌓여 있는 프로세스에 대응되는 태스트 디스크립터(task descriptor)의 last_arrival이란 변수의 순서대로 정렬을 한 다음에 각각 프로세스 별로 스택 바운더리에 대한 스캔을 하면 좋을 것 같어. 이런 매카니즘으로 디버깅을 하면 사이드 이팩트나 시스템 성능 저하로 인한 커널 패닉이 일어나지는 않을 것 같다.

아니면 arm gcc에서 릴리즈하는 __builtin_return_frame이란 매크로 함수를 사용하는 것도 생각해 볼 수 있지. schedule 시 자주 호출하는 함수에 __builtin_return_frame(0)이란 함수를 추가해서 current란 매크로를 통해 현재 프로세스의 스택 경계 주소를 넘어섰는 지를 알아 볼 수도 있어."

물론 이런 종류의 주제에 대해 대화를 나누는 것은 반드시 필요하다. 우리와 같은 임베디드 개발자들이 업무이자 삶이기 때문이다. 그런데 만날 때 마다 이런 이야기만 하면 어떤까?

내가 쉬는 시간에 직장 동료들과 차를 마시며서 나누고 싶은 대화는 하고 있는 일이 힘든지, 주말에 뭐 했는지, 캠핑으로 갈 곳은 어떤지 등등이다. 인간 대 인간으로 소통하고 싶은 것이다. 그런데 문제는 70%정도 나의 직장동료들은 자신들이 좋아하는 기술적인 주제에 대해서만 끊임없이 이야기를 하고 싶어 한다. 이럴 때 난 도무지 로봇이랑 이야기를 하고 있는 것 같다.

아무리 많은 시간 이런 주제들에 대해서 서로 떠들어댄다고 해도 서로에게 어떤 친밀감이 생길 수 있을까? 다만 서로 어떤 기술에 대한 관심사가 있는 지에 대해서 알 수 있는 것이다. 이런 유형의 임베디드 개발자들은 감성이 매우 메말라있거나 사람을 어떻게 대해야 할 지 모르는 경우가 많다.

저번에 팀 회식에서 한 주임 연구원이 "요즘 정말 힘들다"라고 한 숨을 쉬며 말했다. 내가 봐도 그 친구가 엄청난 업무량과 압박감으로 스트레스를 많이 받고 있다는 것을 한 눈에 알 수 있었다. 일할 때 그 친구의 표정, 담배를 필 때의 고뇌에 찬 눈빛을 보기도 했지만, 그 친구가 처해 있는 상황(처음 엠베디드 개발 업무를 맡았는데 멘토가 없음)을 알고 있었기 때문이다. 난 처음 임베디드 개발을 할 때 그 아찔한 느낌을 아직도 생생히 기억한다. 한 겨울에 목욕탕에 들어가자 마자 바로 80도의 펄펄 끓는 온탕에 바로 들어가는 느낌.

그런데 그 친구의 넋두리를 듣던 내 직장 동료와 부서장이 정말로 예술적이면서도 창의적인 질문을 했다.
"니가 힘든 이유에 대한 백데이터(근거 자료, back data)가 뭐야? 한번 제시해 봐."

뜨악! 술이 확 깨는 순간이다. 커널에 로그가 남듯이 사람의 감정에도 로그가 남는 다고 생각하나? 정말 전두엽에 빵꾸가 난 놈이 아닐까? 정말로 내 상식으로 도저히 이해가 가지 않았다. 뭐 이 때의 느낌을 설명할 만한 단어가 떠오르지 않는다. 충격적이고 파괴적이라고 해야 할까. 내가 좀 극단적인 예시를 든 것 같지만 임베디드 개발에 과몰입한 개발자들의 모습을 볼 수 있는 하나의 그림자라고 봐야 겠다.

이렇게 팀동료의 입장에서 생각을 하지 못하고 오직 기술적으로 세상을 바라보다 보니, 다른 동료들과 업무 상 의사소통을 제대로 할 수 없다. 그래서 이들은 사람들과 제대로 어울릴 줄을 모르고 어울린 다고 해도 코드가 맞는 한 두명의 개발자들하고만 소통한다.  

그래서 다른 분야 개발자들은 임베디드 개발자들과 일하기 어렵다는 말을 종종한다. 대부분 의사소통 문제다. 



양극화는 우리 사회가 겪고 있는 심각한 문제 중 하나다. 


양극화를 아주 이해하기 쉽게 설명하면, 

잘사는 가정에서 태어난 아이들은 평생 부유한 환경과 유리한 조건에서 살고 못사는 집안의 아이는 평생 라면만 먹고 산다는 것이다. 


양극화의 가장 큰 원인은 교육 기회의 박탈이다. 못사는 집안의 아이들은 부유한 가정의 아이들에 비교해 교육 환경이 좋지 못하니 좋은 대학에 가지 못하고 이로 좋은 회사에 취업도 못해 가난의 대물림이 계속된다는 것이다. 


이 문장을 임베디드 개발 양극화 관점으로 바꿔 표현해보자. 

좋은 개발 부서에서 실무 프로젝트를 수행한 개발자는 계속 실력이 향상하며 좋은 대우를 받으나 허접한 개발 부서에서 개발을 시작한 개발자는 개발 능력이 업그레이드되지 않아 평생 라면만 먹으며 낮은 연봉을 받으며 일한다는 것이다. 


그러면 임베디드 개발자도 양극화가 있을까? 내가 겪어 본 바로는 개발자 양극화도 심하다고 본다. 

내가 말하는 양극화는 기회의 박탈이다. 즉 실무 경험을 통해 개발 능력을 키울 기회를 의미한다. 


임베디드 개발자 등급도 소고기 등급과 같이 특급부터 3등급까지 여러 등급으로 나눌 수 있는데 언제 등급이 매겨지는지 살펴보자. 


가장 크게, 임베디드 개발자 등급은 취업할 때 입사하는 회사에 따라 나눠진다. 

여기서 말하는 회사는 연봉과 이름값만을 의미하지 않는다. 역량 있는 개발자로 성장할 수 있는 실무 프로젝트를 할 수 있는 회사다. 


아래 조건에서 임베디드 시스템을 개발을 시작하는 개발자는 우선 3~4등급으로 분류될 수밖에 없다. 왜냐? 

제대로 개발을 안 하니 실무능력이 쌓이지 않기 때문이다. 


1. 임베디드 장비로 디바이스 테스트만 하거나 시간을 많이 갈아 넣으면 할 수 있는 소모적인 일을 하는 개발 부서 

2. 코딩한 줄 하지 않고 다른 업체가 포팅한 드라이버를 올려 테스트를 하며 갑질을 하는 개발 부서 

3. 이미 안정화된 리눅스 커널에 드라이버 코드만 약간 수정하면서 프로젝트를 진행하는 개발 부서 

4. 남들이 해 놓은 드라이버를 컴파일이나 빌드를 빨리 해서 디바이스에 올리는 일을 하는 개발 부서 


회사의 이름 네임밸류가 높거나 연봉이 높다고 해도 이런 조건으로 일하는 임베디드 개발자의 역량을 인정해 줄까?


절~대 그렇지 않다. 


임베디드 개발자의 생명은 디버깅 능력이라 생각한다. 디버깅 능력은 문제 해결 능력과 직결되며 문제 해결 능력이 없는 개발자는 이 업계에서 인정해주지 않는다. 그런데 제대로 실무 프로젝트를 맡으며 만나는 여러 문제를 해결하는 과정이 필요한데 이런 **기회**를 박탈당한 개발자는 디버깅 기술 역량이 업그레이드되지 않는다. 


내가 여러 임베디드 모임이나 친구들과의 교류로 알게 된 사실은 많은 한국 임베디드 회사는 제대로 개발을 안 한다는 것이다. 

그 이유는 한국 임베디드 IT 업체들은 실리콘 밸리에 있는 개발자와 경쟁할 수 있는 원천 기술이 녹아 있는 소프트웨어를 개발하려는 의지가 보이지 않기 때문이다. 대부분 미국 등 해외 업체가 구현한 소프트웨어를 올려서 커스터마이즈하는 수준의 일을 하는 경우가 많다. 


그럼 이제 1차 관문에서 다른 임베디드 개발자 등급은 가려졌으니 이제 1등급부터 특급으로는 가는 길만 있지 않을까? 

하지만 현실은 그렇지 않다. 운 좋게 1차 관문을 통과해서 좋은 회사에 취업해도 3~4등급으로 떨어질 수 있다. 


제대로 실무 경험을 쌓을 수 있는 회사에 배치됐다고 해도 그 부서 배치나 그 부서의 개발자 육성 정책에 따라 개발자 등급이 또 나뉘기 때문이다. 


1. 회사의 운명을 결정 짓는 최신 임베디드 시스템을 개발하는 부서에 배치된 경우 

- 쟁쟁한 개발자 틈에서 맨날 테스트만 한다. 

- 핵심 디버깅 기법은 핵심 개발자들끼리 이야기하고 공유하지 않는다. 

- 맨날 이메일을 쓰면서 다른 업체 인터페이스 역할만 한다. 


2. 정치 싸움에 밀려 개별화만커스터마이즈만 하는 프로젝트를 하는 개발 부서에 배치 

- 빌드 머신이 되어 하루에 3~4개씩 이미지를 배포하고 테스트만 한다. 코드 분석할 시간은 물론 없다. 

- 커스터마이즈만 하는 일만 하는 부서이니 선배 개발자 개발 능력이 허접해 배울 것이 없다. 


이름 값하는 회사에서도 벌레처럼 기어다니듯 개발자도 수 없이 많다.


제대로 개발 능력을 키울 수 있는 프로젝트에 투입되는 것이 현실에서는 **정말** 쉽지 않다. 

1~2 관문을 통과하고 정말 실무 경험을 키울 수 있는 프로젝트에서 일하면 특급 개발자가 될 수 있나? 

그렇지 않다. 끊임없는 노력으로 학습을 해야 특급 개발자가 될 수 있는 것 같다.

리눅스 커널은 오픈 소소다. 모든 개발자나 학생들이 소스 코드를 들여다볼 수 있어 많은 정보를 알 수 있다. 함수 이름과 자료 구조를 보면서 리눅스 커널을 익힐 수 있다. 


난 운영체제를 소스 코드를 보면서 익힐 수 있는 리누즈 토발즈 및 오픈 소스 정신을 부르짖는 분들께 감사를 드리고 싶다. 리눅스 커널이 오픈 소스 프로젝트가 아니였다면 난 아마 RTOS 운영체제로 임베디드 디바이스 개발을 했거나 아예 다른 오픈 소스 프로젝트에 뛰어들었을 지도 모른다.

RTOS 회사가 알려주는 운영체제 개념도를 보면서 **그려러니** 하며 머릿속 개념으로 남아 있을 것이다.  


오픈 소스인 리눅스 커널로 누리는 혜택(?)이 있지만 만만치 않은 걸림돌이 있다.

리눅스 커널 소스 코드를 이해하면서 읽기가 너무 어렵다는 것이다. 구조체와 자료 구조가 너무 복잡하다. 


또한 리눅스 커널 소스에서 매크로를 정말 많이 쓴다. 그런데 매크로가 매크로를 5중으로 치환하면서 함수에서 쓰는 매크로 실제 값을 알기도 어렵다.


한 가지 예를 들어보자. 다음은 워크 멤버 중 data 필드로 워커 풀을 읽는 함수다.

static struct worker_pool *get_work_pool(struct work_struct *work)

{

unsigned long data = atomic_long_read(&work->data);

int pool_id;


assert_rcu_or_pool_mutex();


if (data & WORK_STRUCT_PWQ)

return ((struct pool_workqueue *)

(data & WORK_STRUCT_WQ_DATA_MASK))->pool;


pool_id = data >> WORK_OFFQ_POOL_SHIFT;

if (pool_id == WORK_OFFQ_POOL_NONE)

return NULL;


return idr_find(&worker_pool_idr, pool_id);

}


WORK_STRUCT_WQ_DATA_MASK이란 매크로 변수가 어떤 값인지 바로 이해할 수 있나?


다음 코드 선언부와 같이 WORK_STRUCT_FLAG_MASK 매크로를 알려면 WORK_STRUCT_FLAG_MASK, WORK_STRUCT_FLAG_BITS, WORK_STRUCT_COLOR_SHIFT, WORK_STRUCT_COLOR_BITS 매크로를 알아야 한다.

WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,

WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,

WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT +  WORK_STRUCT_COLOR_BITS,


WORK_STRUCT_COLOR_SHIFT 매크로를 분석하려고 하는데 어라? CONFIG_DEBUG_OBJECTS_WORK이란 컨피그에 따라  WORK_STRUCT_COLOR_SHIFT값이 달라진다. 

enum {

WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */

WORK_STRUCT_DELAYED_BIT = 1, /* work item is delayed */

WORK_STRUCT_PWQ_BIT = 2, /* data points to pwq */

WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */

#ifdef CONFIG_DEBUG_OBJECTS_WORK

WORK_STRUCT_STATIC_BIT = 4, /* static initializer (debugobjects) */

WORK_STRUCT_COLOR_SHIFT = 5, /* color for workqueue flushing */

#else

WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */

#endif 


최소 3~4년 리눅스 디바이스 드라이버를 만지면서 실무 개발에 뛰어든 개발자들을 제외하고 리눅스 커널을 처음 소스 코드로 공부한다는 것은 불가능하다. 


다른 이유는 뭘까? 

분석 중인 소스 코드가 실제 리눅스 시스템에서 어떻게 실행하는지 모르기 때문이다. 좀 유식한 말로 콜스택을 알 수 없기 때문이다.  

또한 분석 중인 코드가 컴파일되는 코드인지 모를 때도 있다. 

아예 컴파일 되지 않는 코드를 깊게 분석을 하는 가련한 개발자들을 보면 참 측은한 마음이 생긴다. 말 그대로 개삽질을 하고 있기 때문이다.


리눅스 커널을 익히기 어려운 또 다른 이유는 뭘까?

리눅스 커널을 쉽게 익힐 수 있는 툴이 부족하다. C# 프로그래밍을 하려면 C#용 Studio 프로그램을 설치하고 코딩을 하면 된다. 

그런데 리눅스 커널을 쉽게 설치하고 코딩할 수 있는 시스템이 있나? 사실 없다고 봐야 한다. 컴퓨터에 Ubuntu를 직접 설치하고 크로스 컴파일러 환경을 설정한 후 일일이 명령어를 입력해야 한다. 시스템에서 구동시키려면 엄청 손이 많이 간다. 


마지막으로 리눅스 커널을 쉽게 설명한 책이나 블로그도 없다. 

너무 이론 위주로 설명된 책이 대부분이라 신입 개발자들은 무슨 소리인지 알기 어렵고 블로그도 대부분 소스 코드 몇 줄 복사해 놓고 간단한 분석 내용을 요약해 놓은 수준에 불과하다. 


해외 신입 리눅스 개발자들은 한국과 상황이 약간 다르다. 해외 사이트의 경우 Stack Overflow나 영어로 된 리눅스 커널 입문자들을 위한 사이트가 많다. 영어만 제대로 해도 많은 정보를 얻을 수 있다.


리눅스 커널은 오픈 소스 프로젝트이지만 한국 신입 개발자들에겐 사실상 오픈 프로젝트가 아니다. 리눅스 커널 앞에 거대한 기술 장벽이 있다는 생각이 든다.

하지만 한국의 경우 이런 리눅스 커널을 익히기 위한 인프라가 절대적으로 열악하다.


4차 산업 혁명 시대가 열리면서 리눅스 디바이스 수요도 증가하고 있다. 수요 맞게 리눅스 커널 인프라를 한국에도 깔 필요가 있다. 

+ Recent posts