Linux OS 부팅 과정

컴퓨터공부/리눅스 2016.10.02 17:18 Posted by 아는 개발자

이번 글을 리눅스 OS가 설치된 컴퓨터가 부팅 되는 과정을 설명하는 포스트다. 부트로더가 하는 역할과 초기 부팅시 커널 이미지가 어떤 작업을 하는지 파악하는것에 초점을 두고 작성했으며 중간중간 이들의 정의도 포함되있다.


http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html 페이지를 참고해서 글을 작성했다.


1. 컴퓨터 전원 On


사용자가 컴퓨터 전원을 키면 메인보드에서는 전원이 켜진것을 확인하고 특정 저장위치에 심어둔 부트로더를 실행시킨다.


2. 부트로더(Boot loader)


부트로더의 기능은 말그래도 부팅할 때(Boot) 로드(Load)하는 역할을 한다. 무엇을 로드하는지가 중요한데 OS에 따라 다르지만 리눅스를 기준으로 설명하면, 부트로더는 리눅스가 구동할 커널 이미지(zImage)와 부팅 디바이스의 정보(device tree block)를 로드하는 역할을 한다. 커널이미지와 device tree block은 디스크 저장소에 존재한다. 사용자가 부트로더 어떤 부분을 읽어오라 설정을 하면 바이오스는 해당 위치에 존재하는 바이너리 파일(이미지)를 읽어오도록 구동된다. 여기서 어떤 하드디스크를 사용하느냐에 따라 로딩 속도가 달라진다. SDD가 HDD보다 부팅속도가 빠른것도 위와 같은 이유 때문이다.




로드 하는 곳은 특정 램 영역이다. 커널 이미지는 컴퓨터가 꺼지기 전까지 항상 램 영역에 상주해 컴퓨터 작동에 필요한 코드를 제공한다. 커널 이미지가 위치하는 램 영역 또한 부트로더를 이용해 설정이 가능하다.


대표적인 부트로더로는 바이오스와 u-boot가 있는데 사용하는 Architecture로 구분된다. x86은 주로 바이오스를 사용하고 ARM은 u-boot를 사용한다. 그런데 요새는 둘다를 통합 할 수 있는 UEFI를 사용하는 추세다.


3. 커널 이미지 코드 실행


부트로더 작업이 모두 끝나면 부트로더는 CPU가 다음에 실행하는 코드 (pc값)을 커널 내부로 넘겨서 제어권을 커널에게 줘버린다. 그러면 이제부턴 온전히 커널의 독무대이다. 


( Program Counter 값을 커널 이미지가 위치한 곳으로 옮겨서 앞으로 커널 코드를 수행하도록 한다 )


커널은 개발자가 작성해둔 작업들을 실행한다. 그 작업들로는


      • 페이지 테이블 초기화 작업
      • 하드웨어 초기화 작업(블루투스, 마우스, 키보드 등등...)
      • 드라이버 초기화 작업
      • 네트워크 접속
      • Secondary core 초기화 작업
      • 등등.. 무수히 많다...
OS를 실행 할 때 필요한 초기화 작업들을 모두 한다. 맨처음 부팅할 때 나오는 커널 메시지들이 요런 녀석들이다. 컴퓨터 킬 때 스크린에서 한 번 쯤 봤을 로그들이다.


[    0.191970] ... value mask:             0000ffffffffffff

[    0.191971] ... max period:             000000007fffffff

[    0.191972] ... fixed-purpose events:   0

[    0.191972] ... event mask:             000000000000000f

[    0.193308] x86: Booted up 1 node, 1 CPUs

[    0.193310] smpboot: Total of 1 processors activated (5184.01 BogoMIPS)

[    0.193488] NMI watchdog: disabled (cpu0): hardware events not enabled

[    0.193489] NMI watchdog: Shutting down hard lockup detector on all cpus

[    0.193643] devtmpfs: initialized

[    0.193898] evm: security.selinux

[    0.193899] evm: security.SMACK64

[    0.193900] evm: security.SMACK64EXEC

[    0.193900] evm: security.SMACK64TRANSMUTE

[    0.193901] evm: security.SMACK64MMAP

[    0.193902] evm: security.ima

[    0.193902] evm: security.capability 


맨 처음 시작 할 때의 코드는 head.S 이다. 코드는 요기에 있다. 첫 실행 파일은 어셈블리 언어로 이뤄져 있다. 부팅에 필요한 기본적인 작업들만 수행하고나서 커널로 점프를 한다.


linux/arch/arm/boot/compressed/head.S -> ARM버전

linux/arch/x86/boot/compressed/head_32.S -> x86 32bit 버전


부팅이 정상적으로 마무리 되면, 커널은 루트파일 시스템을 mount하는 작업을 한다.


4. 루트파일 시스템에 mount 작업


마운트 하는 작업을 설명하기 전에 먼저 루트파일 시스템에 대해서 설명부터 하자. 리눅스 커널을 사용하는 OS로는 CentOS, 우분투, 레드햇, Fedora 등등 여러가지가 있다. 그러나 동일하게 리눅스 커널을 사용하기는 하는데 막상 부팅하고 보면 로그인 화면은 모두 차이가 난다. 사용하다보면 폰트도 다르고, 루트 파일의 폴더명도 다르며 패키지 관리 방식과 네트워크 설정 화면 등등 모든것이 다르다. 이것들은 모두 루트파일 시스템이 달라서 그런 것이다. 동일한 리눅스 커널을 사용한다는 것은 최하윗단에서 하드웨어의 리소스를 관리를 리눅스 코드를 사용한다는 것이지 이들의 GUI가 동일하다는 것은 아니다. 커널 소스를 제외한 껍데기(GUI, 기본 명령어, 폴더명 등등...)를 말하는 것이 루트파일 시스템이다. 


커널은 부팅과정에서 자신이 할 일을 마치면 개발자가 미리 설정해둔 루트 파일 시스템 파티션에 mount작업을 실시하고 루트 파일 시스템 실행시 필요한 작업들을 실행한다. OS 버전마다 초기에 시작하는 프로그램이 다르고 또 이들을 실행하는 방식이 다르다. 크게 init.d, systemd로 나뉜다. init.d로 설명하면 pid 1번으로 등록되는 init process가 부팅에 필요한 프로그램들을 실행시킨다.


( 루트파일 시스템 실행중 나오는 로그 )


정상적으로 마운트 되고나면 각 OS마다 제공하는 로그인화면이 뜨게 된다. 모든 부팅이 종료된 상황이다.