반응형

리눅스가 인기 있는 이유

  1. 누구나 소스코드를 볼 수 있다. 리눅스는 크게 리눅스 커널과 리눅스 유틸리티 2가지로 구성되어 있는데 대부분 코드가 공개되어 있다.
  2. 누구나 참여할 수 있는 개방적인 오픈소스 프로젝트이다. 리눅스 소스코드를 분석하다가 버그나 논리적인 오류를 발견하면 누구나 리눅스 오픈소스 프로젝트에 반영할 수 있고, 가독성이 떨어지는 코드를 리팩터링(Refectoring)한 코드를 반영할 수도 있다.
  3. 빠르게 도움을 받을 수 있는 리눅스 커뮤니티 각 기능마다 메일링 리스트를 통해 전 세계 개발자들이 아래와 같은 주제로 토론을 할 수 있다.
  • 커널 버그
  • 커널 개선 패치
  1. 다양한 CPU 아키텍처를 지원한다. 리눅스는 다양한 CPU 아키텍처를 지원하도록 설계돼 있으므로, CPU 아키텍처에 맞춰 리눅스를 빌드하면 리눅스를 실행할 수 있다.

리눅스를 배워야 하는 이유 3가지

  1. IT 산업 전반에서 쓰이는 운영체제이다. (데스크탑, 모바일, 클라우드 서버, 네트워크 장비, 전기 자동차, IoT 디바이스 등)
  2. 다양한 프로그램을 실행하고 운영하기 위함이다. (네트워크, 브라우저, WAS 웹 애플리케이션, 보안 유틸리티 등)
  3. 오픈소스 기반 운영체제이다. (요즘 말하는 리눅스란 하드웨어를 제어하는 리눅스 커널과 그 위에서 실행되는 리눅스 유틸리티로 구성되어 있는데 리눅스의 소스 코드 대부분이 오픈되어 공개되어 있습니다.)

아래의 기술들이 리눅스 시스템 프로그램이나 리눅스 디바이스 드라이버에 구현되어 있다.

  • 운영체제 핵심 기능
  • 각종 보안 기술
  • 네트워크 패킷 통신
  • 각종 센서 드라이버
  • 메모리 시스템
  • CPU 아키텍처(ARM, x86): 인셉션, 인터럽트, 메모리 관리
  • 파일 시스템과 SD 카드

리눅스 커널을 공부해야 하는 4가지 이유

새로운 소프트웨어 기술을 배우는 과정은 크게 두 가지가 있다.

  1. 프로그램을 사용해 본다.
  2. 코드를 작성하거나 소스코드를 분석한다.

리눅스 커널을 반드시 배울 필요는 없지만, 리눅스 고급 개발자 또는 엔지니어로 실력을 인정받고 오랫동안 리눅스 개발을 하고 싶다면 배워야 한다.

  1. 임베디드 리눅스 혹은 BSP(Board Support Package) 개발자로 디바이스 드라이버 개발을 맡는다면, 디바이스 드라이버는 커널 함수를 호출하는 방식으로 구현돼 있기 때문이다.
  2. 고급 리눅스 시스템 프로그래머가 되려면 리눅스 커널을 알아야 한다. (리눅스 시스템 프로그램은 아래와 같은 함수로 구성되어 있다.)
  • 파일 처리 관련 함수 : open(), read(), write(), close()
  • 프로세스 처리 관련 함수 : fork(), getpid(), exit()
  • 시그널 처리 관련 함수 : sigaction(), pause()

위의 함수들을 실행하는 주체는 리눅스 커널이며, 위의 함수들을 호출했을 때 실제로는 리눅스 라이브러리 함수가 이를 처리하는 것이 아닌 리눅스 라이브러리의 도움으로 POSIX 시스템 콜을 호출하여 커널이 동작한다.

한 가지 예시로는 리눅스 시스템 프로그램으로 위의 함수들을 호출했을 때 함수에서 에러를 반환한다면, 이는 리눅스 라이브러리가 아닌 리눅스 커널이 반환하는 것이다. 3. 운영체제의 핵심 원리를 소스코드 분석으로 배울 수 있다.

  • CPU 아키텍처(ARM, x86) : 익셉션, 인터럽트, 메모리 관리
  • 스케줄링
  • 시스템 콜
  • 시그널
  • 가상 파일 시스템
  • 메모리 관리
  1. IT 산업을 이루는 제반 기술을 세부 구현 방식으로 알 수 있습니다. (파일 시스템, 메모리 관리, 네트워크, 이더넷 등)

운영 체제는 응용 프로그램들과 하드웨어 사이에 존재한다.

사용자

응용 프로그램

운영체제

하드웨어

일반 사용자라면 운영체제나 커널에 대해서 관심이 없기도 하고 없어도 되지만, 일반 사용자가 아닌 개발자라면 작성한 코드의 핵심 동작 원리를 파악하기 위해 운영체제의 핵심인 커널을 잘 이해하고 있어야한다.

유저 애플리케이션 : 리눅스 표준 함수를 호출하면 시스템 콜을 통해 실제로 커널이 동작

디바이스 드라이버 : 디바이스 드라이버는 커널이 제공하는 함수를 사용하므로 실제 커널이 동작

실제로 리눅스는 데스크탑과 모바일 등 여러 분야에서 사용되고 있고, 아직 데스크탑에서는 Windows가 더 많이 쓰이겠지만, 모바일에서는 압도적으로 유닉스 계열 운영 체제(IOS, 리눅스)가 사용되고 있다.


1973년 멀틱스 → 유닉스 → 리눅스

리눅스의 모태는 유닉스이고, 유닉스의 모태는 멀틱스이다.

컴퓨터는 발명된 이후 한동안 한 가지 프로그램만 실행이 가능했는데, 예를 들어 음악 CD를 재생하는 컴퓨터가 있다면, 오직 CD만 재생하는 프로그램만 실행할 수 있었다.

하지만 점점 시간이 흘러 컴퓨터는 1개 이상의 프로그램을 실행할 수 있는 수준으로 컴퓨팅 속도가 빨라졌고, 이에 따라 컴퓨터 공학자들은 새로운 소프트웨어를 만들어 보려는 프로젝트를 하게 되는데, 이 프로젝트가 바로 멀틱스 운영체제이다.

멀틱스 운영체제

1965년 MIT, AT&T 벨 연구소, 제네럴 일렉트릭(General Electric) 소속 개발자들이 모여 멀틱스(Multics)라는 운영체제를 개발하기 시작하였고, 이 중에는 '켄 톰슨'과 '데니스 리치'도 포함되어 있었으며, 구현하고자 했던 운영체제의 핵심 기능은 멀티태스킹을 지원하는 운영체제를 구현하는 것이었다.

하지만 멀틱스 운영체제는 실패로 돌아갔고, 이후 멀틱스 프로젝트에 투입됐던 '켄 톰슨'과 다른 개발자들은 멀티태스킹과 멀티 유저를 지원하는 운영체제를 개발하는 것을 목표로 지속적으로 운영체제 연구에 몰두하게 된다.

그리고 그 과정에서 탄생한 것이 바로 PDP-7이라는 소형 컴퓨터에서만 실행가능하도록 어셈블리어를 사용하여 구현된 '유닉스'라는 운영체제이다.

유닉스 운영체제

하지만 이 때의 유닉스는 호환성이 너무 좋지 않았는데 그 이유는 PDP-7가 아닌 다른 기종의 CPU가 탑재된 컴퓨터에서 유닉스를 쓰려면 해당 기종에 맞는 어셈블리어로 새롭게 코드를 작성하여 새 CPU 아키텍처에 맞는 유닉스를 구현해야 했기 때문이다.

위의 상황을 요즘 상황에 맞게 표현하자면 x86 어셈블리 명령어로 구현된 리눅스의 전체 소스코드를 ARMv8 명령어로 전부 바꿔서 개발해야 하는 것이다.

이후에 유닉스의 호환성 문제를 개선하기 위해 '데니스 리치(Dennis Ritchie)'는 새로운 프로그래밍언어를 개발했고, 이 언어가 바로 C언어이다.

그리고 어셈블리 명령어로 구현됐던 기존의 유닉스를 C언어를 사용하여 새로 작성하고 새로운 버전의 유닉스를 개발한다.

C언어로 작성된 유닉스는 개발 속도에 가속도가 붙게 되었고, 이에 맞추어 대학과 연구기관에 소속된 개발자들이 유닉스 기능을 구현하게 되면서 유닉스는 여러 기기에서 실행할 수 있는 호환성과 이식성을 갖추어 점점 제품으로 상용화할 수 있는 수준의 운영체제로 발전한다.

여기까지가 유닉스의 중반기 시절이며, 유닉스가 빠른 속도로 완성도가 높아진 이유는 2가지가 있다.

  1. 유닉스의 소스코드를 오픈소스화해서 무료로 대학기관이나 연구소에 배포했다. 처음에는 연구 목적으로 유닉스의 소스코드를 분석했지만, 여기서 한걸음 더 나아가 유닉스의 코드를 개선하면서 유닉스 프로젝트에 기여하게 된다.
  2. 어셈블리 명령어에서 C언어를 사용함으로써 이식성과 호환성을 높였다. 유닉스는 발전을 거듭하여 다양한 버클리 유닉스(Berkeley Unix, BSD), SYSV 계열로 분화되어 현재까지 리눅스와 더불어 다양한 유닉스 계열 운영체제가 사용되고 있다.

1984년 유닉스 유료화와 무료와 그리고 GNU 단체와 FSF 재단 설립

유닉스는 AT&T 회사의 벨 연구소에서 개발되고 있었는데 AT&T가 전화기를 비롯하여 전자 및 컴퓨터 사업까지 사업 영역을 넓히다 보니 규모가 커졌고, AT&T가 거대 기업이 되다 보니 미국도 AT&T에 의존하게 되는 상황에서 AT&T는 '반독점 소송'을 당하고 패소하게 되는데 1984년 미국 법원은 AT&T를 7개의 회사로 나누고, AT&T가 컴퓨터 사업에 손 대지 못하게 한다.

(7개 회사 중에는 지금도 유명한 버라이즌, 루스튼 등등이 있다.)

그래서 AT&T는 수년 동안 유닉스를 개발하고도 이를 컴퓨터 제품으로 만들 수 있는 개발 인프라를 구축할 수 없게 되다 보니 유닉스를 더 이상 연구할 필요성이 없어졌고, 그에 따라 유닉스를 돈을 받고 팔게 된다.

하지만 유닉스를 여러 회사에 팔다보니 유닉스의 변종들이 생겨났고, 이를 예방하기 위해 '유닉스에 대한 표준을 맞춰 보자'라는 목적으로 POSIX라는 규격이 만들어지게 되며, 이후 여러 유닉스 벤더들은 POSIX 규약에 맞추어 호환성을 유지한 유닉스 제품을 개발하게 된다.

그런데 유닉스 개발에 참여했던 대학이나 연구기관은 유닉스가 유료화가 되면서 더 이상 유닉스의 소스코드를 무료로 볼 수 없게 됐고, 오직 AT&T에게서 유닉스를 구매한 컴퓨터 업체의 개발자들만 유닉스의 소스코드를 분석하면서 개발할 수 있게 되다 보니 불만이 생겼고, 이에 유닉스의 유료화에 반기를 들고 새로운 무료 버전의 유닉스를 만들자는 취지의 GNU(GNU is not UNIX) 단체가 생겨난다.

GNU 단체는 리처드 스톨만(Richard Stallman)을 중심으로 설립됐고, 이후에 FSF(Free Software Foundation) 재단을 설립하면서 무료 유닉스 개발에 착수한다.

시간이 흘러 수백만 명이 참여하는 프로젝트로 규모가 커지게 되고, 그래서 유닉스 유틸리티와 같은 유닉스 기능을 다시 구현하게 됐는데 기존의 유닉스보다 더 완성도가 높은 코드로 만들어진다.

이처럼 유닉스 유틸리티를 하나씩 구현하면서 유닉스를 구성하는 소프트웨어를 만들기 시작하게 되고, 유닉스라는 프로그램을 구조적 관점에서 보면 유닉스를 구동하는 핵심 코어인 유닉스 커널과 그 위에서 실행되는 유닉스 유틸리티가 있다.

유닉스 유틸리티는 여러 개발자들이 모여 어느 정도 완성도를 높여서 개발하지만, 유닉스 커널은 제대로 만들기 어려웠기에 한동안 유닉스 커널 개발이 정체된다.


1992년 유닉스 전쟁

무료 유닉스 개발은 GNU에서만 시도하는 것이 아니였다.

유닉스가 개발되던 초기에는 유닉스 코드를 대학 연구소에 배포했었는데, 그 중 UC 버클리에 속한 BSD(Berkely Software Distribution) 개발자들이 GNU처럼 무료 유닉스 개발을 위해 기존의 유닉스 코드를 재해석하여 1989년 후반 유닉스 커널을 포함한 무료 유닉스를 완성한다.

BSD 개발자들은 AT&T에서 배포판 유닉스 코드를 다시 작성하여 'Net/1'이라는 이름으로 무료로 소스코드를 배포하고, 이후 1991년에 코드 완성도를 높여서 'Net/2'를 공개하게 되는데 1992년 AT&T는 UC 버클리에 AT&T 내부 자료를 이용해 배포판 BSD 유닉스인 'Net/2'는 AT&T의 저작권을 침해했다는 이유로 소송을 건다.

이 소송은 1992년 ~ 1994년까지 2년간 진행됐는데, AT&T USL(Unix System Laboratory)이 노벨에 팔린 후에 AT&T가 소송을 취하하면서 끝나게 되지만, 소송이 진행되는 2년간 UC 버클리에서 BSD 유닉스 개발은 정체되었다.


1991년 리누스 토발즈

BSD 개발자들이 'Net/2'를 공개하던 1991년에 핀란드의 헬싱키 대학에 재학 중이던 리누스 토발즈는 GNU 시스템에 적합한 커널을 직접 개발하여 1991년 8월 25일 GNU 커널을 어느 정도 완성하여 comp.os.minix라는 뉴스 그룹에 글을 올린다.

하지만 초기 버전인 0.01은 정말 기본적인 커널 기능만 지원했는데, 실행도 되지 않았고,

이후 0.02 공식 버전을 발표했는데 BASH(GNU Bourne Again Shell)와 GCC(GNU C 컴파일러) 정도만 실행이 가능한 수준이었다.

다음 년도 3월에 0.95 버전으로 업그레이드 되면서 인텔 x86 칩에서 그래픽 사용자 인터페이스가 추가되었다.

그리고 이 때 스톨만과 FSF는 허드(Hurd)를 GNU 커널로 개발하고 있었는데, 생각보다 허드 개발이 느리자 고민 끝에 리누스 토발즈가 개발한 유닉스 커널을 GNU 커널로 채택하게 되고, 이 과정에서 탄생한 것이 바로 리눅스이며, 기존 GNU 유틸리티와 리누스 토발즈가 개발한 커널이 결합하여 GNU는 완성된 구조를 이루게 된다.


리눅스의 용도

  1. 안드로이드 안드로이드는 리눅스 커널 위에서 동작하고, 안드로이드 개발자는 리눅스 커널을 안드로이드 시나리오에 맞게 수정해서 사용한다.
  2. 자동차 최근 전기자동차 시장이 열리면서 자동차 인포테인먼트(Infotainment) 분야에 리눅스 커널이 활발히 쓰인다. 인포테인먼트 : 자동차의 내비게이션 기능에서 운전자에게 제공하는 다양한 멀티미디어 서비스를 의미한다.
  3. 사물 인터넷 디바이스
  4. TV
  5. 클라우드 서버
  6. 슈퍼 컴퓨터

등등


리눅스 커널 사이트

https://www.kernel.org

리눅스 커널 버전 왼쪽에 'longterm'으로 표시된 부분은 안정화된 리눅스 커널 버전을 의미한다.

LTS(Long Term Support) : 안정화된 리눅스 커널


리눅스 개발과 관련된 단체 1 : cpu 벤더

  • ARM(ARMv7/ARMv8)
  • Intel(x86)
  • IBM(PowerPC)

CPU 벤더들도 리눅스 커널 개발에 참여한다.

아래의 리눅스 커널의 핵심 기능들은 CPU에 따라 구현 방식이 다르기 때문이다.

  • 시스템 콜
  • 익셉션
  • 컨텍스트 스위칭

리눅스 커널은 다양한 CPU 아키텍처와 함께 구동되는데, 커널의 핵심 동작은 서로 다른 CPU 어셈블리 코드로 구현돼 있다.

리눅스 커널은 다양한 CPU 아키텍처를 지원하는 소스 트리를 갖추고 있으며 사용하고자 하는 CPU 아키텍처에 맞춰 빌드하면 이에 맞는 커널 이미지를 생성할 수 있다.


리눅스 개발과 관련된 단체 2 : SoC 벤더

SoC는 System-on-chip의 약자로 하나의 컴퓨터 또는 다른 전자 시스템들의 모든 구성 요소를 통합한 집적회로를 의미한다.

SoC를 개발하는 브로드컴, 삼성전자(시스템 LSI), 퀄컴, 인텔, 미디어텍, 엔비디아 같은 회사를 SoC 벤더라고 한다.

이들은 먼저 리눅스 커널 버전을 선택하고 CPU 벤더로부터 툴 체인을 받아 자신의 SoC 스펙에 맞게 리눅스 커널 코드를 수정하거나 드라이버를 추가한다.

  • 브로드컴 : BCM(bcm2837, 라즈베리 파이에 탑재)
  • 삼성전자(시스템 LSI): 엑시노스(Exynos)
  • 퀄컴 : 스냅드래곤
  • 인텔 : 아톰, 무어필드
  • 미디어텍 : 헬리오
  • 엔비디아 : 테그라

리눅스 개발과 관련된 단체 3 : 보드 벤더 및 OEM

보드 벤더와 OEM(Original Equipment Manufacturer) 업체는 SoC가 Release한 리눅스 커널 코드를 받아 제품 스펙과 시나리오에 맞게 제품을 개발한다.

보드 벤더 : 라즈베리 파이 재단과 같은 업체

OEM : 삼성전자, LG 전자와 같이 상용 제품을 개발하는 업체


임베디드 리눅스 개발을 잘 하려면

좁게 보면

  • 디바이스 드라이버
  • 리눅스 커널
  • CPU 아키텍처
  • SoC

조금 넓게 보면

  • 유저 공간 HAL(Hardware Abstraction Layer) 코드 구현
  • 빌드 스크립트 구현
  • 테스트용 디바이스 드라이버 구현
  • Git과 형상 관리

디바이스 드라이버

  • 인터럽트 핸들러 함수와 인터럽트를 처리하는 방식
  • 디바이스 파일로 open/read/write 여산에 대한 함수를 등록하는 방법
  • 디바이스 트리를 읽어 디바이스 속성을 저장하는 방식

임베디드 리눅스 개발을 시작하면 바로 디바이스 드라이버 업무를 맡는 경우가 많은데 업무 프로세스나 회사 교모에 따라 드라이버 개발 범위가 다르지만, 제품을 구성하는 디바이스 드라이버의 특정 분야를 맡을 수도 있고, 한 명의 임베디드 개바자가 임베디드 리눅스를 책임지는 경우도 있다.

개발에 투입되면 자신이 작성한 디바이스 드라이버 코드보다 다른 사람이 작성한 코드를 읽을 가능성이 높기 때문에 디바이스 드라이버 코드를 빨리 읽고 이해하는 능력을 키우는 것도 중요하다.

리눅스 커널

디바이스 드라이버는 리눅스 커널에서 제공하는 함수로 구성돼 있고 호출한 함수의 동작 방식을 알려면 당연히 리눅스 커널 코드를 분석할 수 밖에 없다.

그리고 디바이스 드라이버를 개발하는 과정은 코드를 입력하여 드라이버를 구현하는 데 그치지 않지만 인증 테스트 부서를 통해 드라이버 안정화 테스트 과정을 거치게 되는데 이 과정에서 접하는 다양한 버그를 수정하여 문제를 해결하기 위해서 리눅스 커널을 잘 알아야 한다.

CPU 아키텍처

리눅스 커널 코드를 조금 깊게 들여다보면 어셈블리 코드를 보게 된다.

리눅스 커널의 핵심 개념들은 대부분 어셈블리 코드로 구현돼 있는데 그 이유는 리눅스 커널의 핵심 동작은 CPU아키텍처와 연관된 부분이 많기 때문이다.

  • 컨텍스트 스위칭
  • 익셉션 벡터
  • 시스템 콜
  • 시그널 핸들러
  • 메모리 관리(MMU)

처음 리눅스를 접한다면 CPU 아키텍처의 세부 동작 원리와 어셈블리 코드를 공부하기 보다는 리눅스 시스템과 커널 로그, ftrace(커널의 세부 동작을 알려주는 유틸리티)에 친숙해지는 것이 먼저이다.

하지만 리눅스 커널을 좀 더 깊게 알고자 한다면 CPU 아키텍처(ARM, x86)에 대해 아래와 같은 내용을 알아야 한다.

  • 어셈블리 언어
  • 익셉션이 발생하는 원리와 익셉션 벡터의 세부 동작
  • 함수 호출 규약(Calling Convention)

빌드 디스크립트와 Git

빌드 스크립트를 잘 이해하고 Git을 잘 다루면 효율적으로 개발할 수 있다

다른 업체가 개발한 드라이버나 응용 프로그램을 현재 사용 중인 소스 트리에 추가해야 할 때가 있는데 이 때 빌드 스크립트와 빌드 구조를 잘 파악하면 업무를 더 빨리 끝낼 수 있다.

또한 실전 개발에서 많은 걸림돌들을 피할 수 있다.


라즈베리 파이란

라즈베리 파이는 전 세계적으로 널리 쓰이는 리눅스 개발용 보드이자 소형 컴퓨터이다.

용도는 교육용으로 주로 쓰이기 때문에 설치 과정이 간단하고, 가격 대비 성능도 좋아 다양한 디바이스 드라이버를 구현하는 데 사용할 수 있다.

그리고 실전 개발에서도 다양한 데모용 디바이스로 자주 활용되고 있다.

장점

  1. 막강한 커뮤니티
  2. 저렴한 가격
  3. 간단한 설치

라즈비안 : 라즈베리 파이에서 구동할 수 있게 리눅스 프로그램과 유틸리티를 패키징한 것


쉘이란

커널과 사용자 간의 인터페이스 역할을 수행하는 텍스트 기반의 명령어 해석기 프로그램이다.

Shell 기능

  • 명령어 해석 기능(Command Line Interpreter, CLI)
  • 프로그래밍 기능
  • 사용자 환경 설정 기능

명령어 해석 기능 : 사용자가 키보드를 통해 입력시킨 명령어 라인을 읽고, 필요한 시스템 기능을 실행시키거나 다른 프로그램에게 넘겨서 실행시키는 작은 프로그래밍 환경처럼 행동하는 명령어 해석기

프로그래밍 기능 : 쉘 스크립트 기능

사용자 환경 설정 기능 : 쉘 변수, 환경 변수 등

유닉스 셸의 기능과 종류

  • 사용자와 커널 사이에서 서로 연결시켜주는 기능을 하는 프로그램으로 해석기, 프로그래밍, 사용자 환경설정 기능들이 있고, 본쉘(Bourne Shell), C 쉘(C Shell), 콘쉘(Korn Shell), 배시 쉘(bash), zsh(Z Shell) 등이 있다.

ksh의 주요 기능

  • 유닉스에서 가장 많이 사용하고 있는 쉘로 명령행 편집 기능을 제공하는데, Bourne shell의 상위 버전이고 C Shell의 특징들을 모두 제공하면서 처리 속도도 빠르다.
  • 명령어 완성 기능과 히스토리 기능 등이 제공된다.

csh의 주요 기능

  • 히스토리 기능, alias(별명) 기능, 작업 제어 등의 기능들이 포함되어 있다.

bash의 주요 기능

  • 여러 운영체제에서 사용 중이며 리눅스의 표준 shell이다.
  • ksh와 csh를 합친 shell로, 히스토리, 명령어 완성기능, 명령어 치환, 명령행 편집 등이 지원된다.

http://www.ktword.co.kr/word/abbr_view.php?m_temp1=994

반응형

+ Recent posts