1. 부트프로세스 / BIOS UEFI

markyang92·2021년 9월 17일
1

boot

목록 보기
1/6
post-thumbnail

부팅 프로세스

  1. BIOS/UEFI ROM 펌웨어가 부트로더를 찾아 로드한다.
  2. 부트 로더가 로드된다.
    2.1. 디스크상의 '커널 이미지'(/boot/vmlinuz-x.x.x-xx 등)를 발견 혹은 위치 로드.
    2.2. Device Tree Pointer를 넘기던 이게 커널에 포함되어 있던 한다.
    2.3. 커널 로드전에 initramfs 실행 유무 및 위치,
    2.4.커널 커맨드(rootfs) 등을 커널에 넘긴다.
  3. (option) initramfs
  4. kernel이 디바이스 및 디바이스 드라이버로 초기화
    4.1.. 커널이 rootfs를 마운트한다.
  5. 커널은 PID 1init 프로세스를 시작한다. 여기서 사용자 공간이 시작된다.
  6. init 프로세스는 시스템 프로세스의 나머지들을 시작 시킨다.
  7. init로그인 프로세스를 시작한다.

1. BIOS/UEFI ROM

1. BIOS/UEFI

  1. BIOS/UEFI가 동작한다.
    • DRAM 컨트롤러가 시작하지 않았기 때문에 main memory에는 접근할 수 없다.
    • 다른 interface도 구성되지 않았기 때문에 NAND 플래시 컨트롤러, MMC 컨트롤러 등을 통해 접근하는 저장소도 사용할 수 없다.
    • 처음에 동작하는 것은 하나의 CPU Core, 약간의 On Chip Static Memory
      • System Bootstrap

  1. 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 + MBRBoot Disk의 0번 섹터가 Boot Sector, 첫 번째 파티션이 Boot Partition
단 Linux의 GRUB는 첫번째가 아닌 파티션을 Boot Partition으로 지정할 수 있다.MBR은 디스크의 어느 파티션에 부트 로더가 존재하는지 정보등이 저장되어 있다.
MBR은 부트 로더메모리에 동작시킨다.
MBR 다음, and 2)첫 번째 파티션 이전. -> BIOS가 GRUB를 로드
UEFI + GPTBoot Disk의 ★ ESP(EFI System Partiton) ★이 Boot Partition
즉, ESPBoot 파티션이고 여기서 GRUB를 로드
UEFI + MBRMBR 디스크 내, ★ ESP(EFI System Partiton) ★을 FAT32 파일 시스템 및 EFI 부트로더를 심으면, UEFI + MBR

2. 부트로더가 'GRUB'인 경우

  • 여튼 위의 ROM이(BIOS+MBR이던, UEFI+GPT던, UEFI+MBR이던 간에) GRUB를 로드하고 나면, 이 시점에서 GRUB는 디스크와 파일 시스템에 접근할 수 있다.
  • GRUBBoot Partition을 확인하고 그 곳에 설정 파일을 로딩한다.
  • 설정을 실행하는 과정에서 GRUBBoot Partition에 추가적인 코드(모듈)을 로딩할 수 있다.
  • GRUBlinux 명령에 의해 명시된 커널을 로드하고, 실행하기 위해 boot 명령을 실행한다.

  • 만약 grub cmdline으로 들어간다면,
> ls
> set root=(hd0,msdos2)
> ls /
> linux <linux커널이미지> root=<rootfs device file>
> initrd <initramdisk이미지>
> boot

  1. 운영체제 커널로드한다.
    2.1. 커널을 찾아 메모리로 올린다.
    • 부트로더와 커널 사이의 인터페이스는 아키텍처별로 다르지만 두 가지 일을 한다.
      1. HW 구성 정보를 담고 있는 구조체의 포인터 전달 : device tree
      2. 커널 커맨드라인의 포인터를 전달한다.
  2. 커널이 실행되면(제어권을 넘기면) 부트로더는 더 이상 필요치 않고, 사용하던 모든 메모리를 회수 할 수 있다.
    3.1. 부트로더 구성을 업데이트
    3.2. 새로운 부트 이미지를 메모리에 로드
    3.3. 진단 기능을 실행하는 유지보수 모드 제공
    • (시리얼 인터페이스를 통한 간단한 커맨드라인 인터페이스로 제어된다.)
  1. 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
  • 커널의 매개변수 중 rootrootfs 위치이다.
$ 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


  1. ROM Code
  • 리셋, 전원을 켠 직후 실행되는 코드는 SoC 칩 상에 저장되어 있다.
    ROM Code는 제조 시, 칩에 프로그램되므로, 비공개(proprietary)이다.
  • DRAM 구성은 장치별로 매우 달라서, 메모리 컨트롤러를 초기화하는 코드는 보통 담고 있찌 않다.
    메모리 컨트롤러가 필요 없는 SRAM(Static Random Access Memory)만 사용 할 수 있다.
    대부분 임베디드 SoC에는 약간의 SRAM을 두는데, 4KB ~ 수백KB까지 다양하다.
  • ROM코드는 SPL(Secondary Peripheral Interface)을 SRAM으로 옮긴다.
    • beaglebone black의 SPLMLO이다.
      • NAND 플래시 메모리의 첫 몇 페이지
      • SPI(Serial Peripheral Interface)로 연결된 플래시 메모리
      • MMC 장치(eMMC, SD카드)의 첫 섹터/ 첫 파티션
        을 찾아 이름이 MLO인 파일을 로드한다.
      • 이 것이 실패하면, ethernet, USB, UART로 부터 Byte Stream을 읽으려한다.

  1. SPL
  • SPL은 메모리 컨트롤러와 기타 TPL(Tertiary Program Loader)를 DRAM에 로드하기 위해 필요한 시스템의 필수적인 부분들을 시작해야한다.
  • SPL의 기능은 크기로 인해 제한된다.
  • SPL에 파일시스템 드라이버가 내장되어 있다면, 디스크 파티션에서 u-boot.img처럼 잘 알려진 파일 이름을 읽을 수 있다.
  • 여튼 SPLTPLDRAM으로 로드한다.

  1. DRAMTPL에 로드되었다. 이제 마침내 u-boot, BareBox 같은 완전한 부트로더를 실행할 것이다.
  • 부트/커널 이미지를 플래시 저장소에 로드
  • initramfs
  • FDT
    로드 후, 커널이 메모리에서 시작되길 기다리고 있다.
    부트로더는 보통 일단 커널이 실행되면 메모리에서 사라지고 커널에게 제어권을 준다.
  • 커널 커맨드라인 -> rootfs 장치 -> initramfs(생략 가능, 램디스크 이미지를 메모리에 로드하는 것은 부트로더의 책임)
profile
pllpokko@alumni.kaist.ac.kr

1개의 댓글

comment-user-thumbnail
2023년 1월 8일

안녕하세요, 요즘 비글본이나 여러 임베디드 관련 지식에 관심이 많아 여기저기 찾아보는 중인데, 이 블로그가 자주 보여서 많은 도움 받고 있습니다. 항상 좋은정보 공유주셔서 감사합니다!

답글 달기