부팅 프로세스
- BIOS/UEFI ROM 펌웨어가 부트로더를 찾아 로드한다.
- 부트 로더가 로드된다.
2.1. 디스크상의 '커널 이미지'(/boot/vmlinuz-x.x.x-xx 등)를 발견 혹은 위치 로드.
2.2. Device Tree Pointer를 넘기던 이게 커널에 포함되어 있던 한다.
2.3. 커널 로드전에 initramfs 실행 유무 및 위치,
2.4.커널 커맨드(rootfs) 등을 커널에 넘긴다.
- (option) initramfs
- kernel이 디바이스 및 디바이스 드라이버로 초기화
4.1.. 커널이 rootfs를 마운트한다.
- 커널은 PID 1인
init
프로세스를 시작한다. 여기서 사용자 공간이 시작된다.
init
프로세스는 시스템 프로세스의 나머지들을 시작 시킨다.
init
은 로그인 프로세스를 시작한다.
1. BIOS/UEFI ROM
1. BIOS/UEFI
- BIOS/UEFI가 동작한다.
- DRAM 컨트롤러가 시작하지 않았기 때문에 main memory에는 접근할 수 없다.
- 다른 interface도 구성되지 않았기 때문에 NAND 플래시 컨트롤러, MMC 컨트롤러 등을 통해 접근하는 저장소도 사용할 수 없다.
- 처음에 동작하는 것은 하나의 CPU Core, 약간의 On Chip Static Memory
- ROM 동작
2.1. ROM code는 디바이스가 Start-Up 또는 Power-on Reset(POR) 이후에 자동적으로 실행되는 코드의 첫 번째 블럭에 있다.
- UEFI의 경우는 프로세서가 플래시 메모리로부터 플랫폼 초기와 펌웨어를 로드한다. (SPL의 역할)
- 어떤 설계에서는 NOR 플래시 메모리에서 직접 로드 (0xfffffffc)에 리셋 벡터... 옛날 방법
- 또 어떤 설계에서는 SPI(Serial Peripheral Interface)플래시 메모리로 부터 칩에 내장된 SRAM으로 펌웨어를 로드하는 칩 내장 롬 코드가 있다.
- 로컬디스크상 ESP(EFI System Partition)이나 PXE 부트를 통해 네트워크 서버에서 EFI 부트 관리자를 로드할 수 있도록 DRAM 컨트롤러와 인터페이스를 초기화한다.
- ESP는 FAT16이나 FAT32 포맷으로 포맷되어 있어야한다.
- 부트 관리자 코드의 경로명은 (efi system partition) /efi/EFI/BOOT/BOOTX64.EFI (x86_64의 경우)
- UEFI 부트관리자는 TPL이다. 이 경우 TPL은 리눅스 커널과 램 디스크(option)를 메모리에 로드할 수 있는 부트로더여야 한다.
- system-boot: 예전에는 gummiboot라고 불렸다. 간단한 UEFI 호환 부트로더고, LGPL v2.1을 따른다.
- Tummiboot: 'trusted boot'(인텔의 TEX(Trusted Execution Technology)가 지원되는 gummiboot
2.2. ROM Code는 두 가지 주요 기능을 한다.
- 디바이스의 Config, Primary peripherals 초기화
- Stack Setup
- configure watchdog timer 1 (set to three mins)
- PLL, System Clock Configuration
- Next Bootloader에 대한 디바이스 준비
- next bootloader용 boot source (SPL) 체크
- 실행될 next bootloader code를 메모리로 로딩
종류 | Boot Partition |
---|
BIOS + MBR | Boot Disk의 0번 섹터가 Boot Sector, 첫 번째 파티션이 Boot Partition 단 Linux의 GRUB는 첫번째가 아닌 파티션을 Boot Partition으로 지정할 수 있다.MBR은 디스크의 어느 파티션에 부트 로더가 존재하는지 정보등이 저장되어 있다. MBR은 부트 로더를 메모리에 동작시킨다. MBR 다음, and 2)첫 번째 파티션 이전. -> BIOS가 GRUB를 로드 |
UEFI + GPT | Boot Disk의 ★ ESP(EFI System Partiton) ★이 Boot Partition 즉, ESP가 Boot 파티션이고 여기서 GRUB를 로드 |
UEFI + MBR | MBR 디스크 내, ★ ESP(EFI System Partiton) ★을 FAT32 파일 시스템 및 EFI 부트로더를 심으면, UEFI + MBR |
2. 부트로더가 'GRUB'인 경우
- 여튼 위의 ROM이(
BIOS+MBR
이던, UEFI+GPT
던, UEFI+MBR
이던 간에) GRUB를 로드하고 나면, 이 시점에서 GRUB는 디스크와 파일 시스템에 접근할 수 있다.
- GRUB는 Boot Partition을 확인하고 그 곳에 설정 파일을 로딩한다.
- 설정을 실행하는 과정에서 GRUB는 Boot Partition에 추가적인 코드(모듈)을 로딩할 수 있다.
- GRUB는
linux
명령에 의해 명시된 커널을 로드하고, 실행하기 위해 boot
명령을 실행한다.
> ls
> set root=(hd0,msdos2)
> ls /
> linux <linux커널이미지> root=<rootfs device file>
> initrd <initramdisk이미지>
> boot
- 운영체제 커널을 로드한다.
2.1. 커널을 찾아 메모리로 올린다.
- 부트로더와 커널 사이의 인터페이스는 아키텍처별로 다르지만 두 가지 일을 한다.
- HW 구성 정보를 담고 있는 구조체의 포인터 전달 : device tree
- 커널 커맨드라인의 포인터를 전달한다.
- 커널이 실행되면(제어권을 넘기면) 부트로더는 더 이상 필요치 않고, 사용하던 모든 메모리를 회수 할 수 있다.
3.1. 부트로더 구성을 업데이트
3.2. 새로운 부트 이미지를 메모리에 로드
3.3. 진단 기능을 실행하는 유지보수 모드 제공
- (시리얼 인터페이스를 통한 간단한 커맨드라인 인터페이스로 제어된다.)
- GRUB의 더 자세하고 수정할 수 있는 설명은 링크: https://velog.io/@markyang92/boot-loader-grub
/proc/cmdline
- 이 파일에는 시스템 부트 에서 전달한 커널 매개 변수들을 확인할 수 있다.
BOOT_IMAGE=/boot/vmlinuz-5.4.0-66-generic root=UUID=732910d6-ddae-4a95-ab9e-9f5c9edc555a ro
- 커널의 매개변수 중
root
가 rootfs 위치이다.
$ blkid
/dev/sda2: UUID="732910d6-ddae-4a95-ab9e-9f5c9edc555a" TYPE="ext4" PARTUUID="344f3148-6593-4bef-9796-185d33f9a2f5"
/dev/sda2
가 rootfs 임을 알 수 있다.
ro
매개 변수는 사용자 공간이 시작되면 rootfs를 읽기 전용 모드로 마운트하도록 커널에 지시한다.
- 읽기 전용 모드는
fsck
가 rootfs를 안전하게 확인할 수 있도록 보장한다.
- 확인 후, 부트업 프로세스가 rootfs를
rw
모드로 다시 re-mount한다.
- 이 커널 매개 변수가 제대로 지정되지 않으면 커널은
init
을 찾을 수 없다. 그러면, 사용자 공간을 시동할 수 없다.
- 커널은 사용자 공간이 시동 될 때, 이 매개 변수를
init
에게 전달한다.
- 만약 커널 매개변수에
-s
가 있으면 single-user mode에서 시작한다는 것이다.
Embedded System Boot
- ROM Code
- 리셋, 전원을 켠 직후 실행되는 코드는 SoC 칩 상에 저장되어 있다.
ROM Code는 제조 시, 칩에 프로그램되므로, 비공개(proprietary)이다.
- DRAM 구성은 장치별로 매우 달라서, 메모리 컨트롤러를 초기화하는 코드는 보통 담고 있찌 않다.
메모리 컨트롤러가 필요 없는 SRAM(Static Random Access Memory)만 사용 할 수 있다.
대부분 임베디드 SoC에는 약간의 SRAM을 두는데, 4KB ~ 수백KB까지 다양하다.
- ROM코드는 SPL(Secondary Peripheral Interface)을 SRAM으로 옮긴다.
- beaglebone black의 SPL은 MLO이다.
- NAND 플래시 메모리의 첫 몇 페이지
- SPI(Serial Peripheral Interface)로 연결된 플래시 메모리
- MMC 장치(eMMC, SD카드)의 첫 섹터/ 첫 파티션
을 찾아 이름이 MLO인 파일을 로드한다.
- 이 것이 실패하면, ethernet, USB, UART로 부터 Byte Stream을 읽으려한다.
- SPL
- SPL은 메모리 컨트롤러와 기타 TPL(Tertiary Program Loader)를 DRAM에 로드하기 위해 필요한 시스템의 필수적인 부분들을 시작해야한다.
- SPL의 기능은 크기로 인해 제한된다.
- SPL에 파일시스템 드라이버가 내장되어 있다면, 디스크 파티션에서 u-boot.img처럼 잘 알려진 파일 이름을 읽을 수 있다.
- 여튼 SPL이 TPL을 DRAM으로 로드한다.
- DRAM이 TPL에 로드되었다. 이제 마침내 u-boot, BareBox 같은 완전한 부트로더를 실행할 것이다.
- 부트/커널 이미지를 플래시 저장소에 로드
- initramfs
- FDT
로드 후, 커널이 메모리에서 시작되길 기다리고 있다.
부트로더는 보통 일단 커널이 실행되면 메모리에서 사라지고 커널에게 제어권을 준다.
- 커널 커맨드라인 -> rootfs 장치 -> initramfs(생략 가능, 램디스크 이미지를 메모리에 로드하는 것은 부트로더의 책임)
안녕하세요, 요즘 비글본이나 여러 임베디드 관련 지식에 관심이 많아 여기저기 찾아보는 중인데, 이 블로그가 자주 보여서 많은 도움 받고 있습니다. 항상 좋은정보 공유주셔서 감사합니다!