운영 체제없이 프로그램을 실행하는 방법은 무엇입니까?


239

운영 체제를 실행하지 않고 어떻게 프로그램을 자체적으로 실행합니까? 컴퓨터를 시작할 때로드하고 실행할 수있는 어셈블리 프로그램을 만들 수 있습니까 (예 : 플래시 드라이브에서 컴퓨터를 부팅하고 CPU에있는 프로그램을 실행)?


4
어느 아키텍처에서? x86? 팔?
Kissiel

1
나는 일반적으로 말하고 있지만 대부분 x86 또는 x64
user2320609

2
그렇습니다. 프로세서가 정확히 부팅되는 방식입니다. 조립할 필요는 없습니다. C는 부트 스트랩 및 기타 지원을 위해 약간의 asm과 함께 사용되는 경우가 많습니다.
old_timer

24
생각해보십시오 : 그러한 기능이 없다면 OS 자체는 어떻게 시작되고 실행됩니까? :)
Seva Alekseyev

답변:


153

운영 체제를 실행하지 않고 어떻게 프로그램을 자체적으로 실행합니까?

이진 코드는 재부팅 후 프로세서가 찾는 위치 (예 : ARM의 주소 0)에 배치합니다.

컴퓨터를 시작할 때로드하고 실행할 수있는 어셈블리 프로그램을 만들 수 있습니까 (예 : 플래시 드라이브에서 컴퓨터를 부팅하고 드라이브에있는 프로그램을 실행)?

질문에 대한 일반적인 답변 : 할 수 있습니다. 종종 "베어 메탈 프로그래밍"이라고합니다. 플래시 드라이브에서 읽으려면 USB가 무엇인지 알고 싶어서이 USB와 작동하는 드라이버가 필요합니다. 이 드라이브의 프로그램은 특정 파일 시스템의 특정 형식이어야합니다. 이것은 부트 로더가 일반적으로하는 작업이지만 프로그램에 자체 부트 로더가 포함되어 있으므로 펌웨어 만 작은 코드 블록을로드하십시오.

많은 ARM 보드에서 이러한 작업을 수행 할 수 있습니다. 일부에는 기본 설정을 도와주는 부트 로더가 있습니다.

여기 에서는 Raspberry Pi에서 기본 운영 체제를 수행하는 방법에 대한 훌륭한 자습서를 찾을 수 있습니다.

편집 :이 기사와 전체 wiki.osdev.org는 대부분의 질문에 답합니다 http://wiki.osdev.org/Introduction

또한 하드웨어를 직접 실험하지 않으려는 경우 qemu와 같은 하이퍼 바이저를 사용하여 가상 머신으로 실행할 수 있습니다. 가상화 된 ARM 하드웨어 에서 직접 "hello world"를 실행하는 방법은 여기를 참조하십시오 .


723

실행 가능한 예제

OS없이 실행되는 몇 가지 미처리 베어 메탈 Hello World 프로그램을 작성하고 실행 해 보겠습니다.

또한 QEMU 에뮬레이터에서 최대한 안전하고 개발하기 편리하도록 시험해 볼 것입니다. QEMU 테스트는 사전 패키지 된 QEMU 2.11.1과 함께 Ubuntu 18.04 호스트에서 수행되었습니다.

아래의 모든 x86 예제 코드는 이 GitHub 리포지토리에 있습니다.

x86 실제 하드웨어에서 예제를 실행하는 방법

실제 하드웨어에서 예제를 실행하는 것은 위험 할 수 있습니다. 예를 들어 실수로 디스크를 지우거나 하드웨어를 손상시킬 수 있습니다. 중요한 데이터가 포함되지 않은 오래된 시스템에서만이 작업을 수행하십시오! 또는 Raspberry Pi와 같은 저렴한 반 일회용 보드를 사용하십시오 (아래 ARM 예 참조).

일반적인 x86 랩톱의 경우 다음과 같은 작업을 수행해야합니다.

  1. 이미지를 USB 스틱에 굽습니다 (데이터가 손상 될 수 있습니다).

    sudo dd if=main.img of=/dev/sdX
    
  2. 컴퓨터에 USB를 연결

  3. 전원을 켜십시오

  4. USB에서 부팅하도록 지시하십시오.

    즉, 펌웨어가 하드 디스크보다 먼저 USB를 선택하도록합니다.

    이것이 시스템의 기본 동작이 아닌 경우 전원을 켠 후 Enter 키, F12, ESC 또는 기타 이상한 키를 계속 누르면 USB에서 부팅하도록 선택할 수있는 부팅 메뉴가 나타납니다.

    해당 메뉴에서 검색 순서를 구성하는 것이 종종 가능합니다.

예를 들어, T430에서 다음을 볼 수 있습니다.

전원을 켠 후 Enter를 눌러 부팅 메뉴로 들어가야합니다.

여기에 이미지 설명을 입력하십시오

그런 다음 F12를 눌러 부팅 장치로 USB를 선택해야합니다.

여기에 이미지 설명을 입력하십시오

여기에서 부팅 장치로 USB를 다음과 같이 선택할 수 있습니다.

여기에 이미지 설명을 입력하십시오

또는 부팅 순서를 변경하고 우선 순위가 높은 USB를 선택하여 매번 수동으로 선택할 필요가 없으면 "시작 인터럽트 메뉴"화면에서 F1을 누르고 다음으로 이동합니다.

여기에 이미지 설명을 입력하십시오

부트 섹터

x86에서 수행 할 수있는 가장 단순하고 가장 낮은 수준의 작업은 부팅 섹터 유형 인 MBR (Master Boot Sector)을 만든 다음 디스크에 설치하는 것입니다.

여기서 우리는 단일 printf호출로 하나를 만듭니다 .

printf '\364%509s\125\252' > main.img
sudo apt-get install qemu-system-x86
qemu-system-x86_64 -hda main.img

결과:

여기에 이미지 설명을 입력하십시오

아무 것도하지 않아도 화면에 이미 몇 개의 문자가 인쇄되어 있습니다. 펌웨어로 인쇄되며 시스템을 식별하는 역할을합니다.

그리고 T430에서 깜박이는 커서가있는 빈 화면이 나타납니다.

여기에 이미지 설명을 입력하십시오

main.img 다음을 포함합니다 :

  • \3648 진수 == 0xf416 진수 : hlt명령어 인코딩으로 CPU가 작동을 중지하도록 지시합니다.

    따라서 우리의 프로그램은 아무것도하지 않을 것입니다 : 시작과 중지 만.

    \xPOSIX에서 16 진수를 지정하지 않기 때문에 8 진수를 사용 합니다.

    이 인코딩을 쉽게 얻을 수 있습니다 :

    echo hlt > a.S
    as -o a.o a.S
    objdump -S a.o
    

    어떤 출력 :

    a.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <.text>:
       0:   f4                      hlt
    

    물론 인텔 설명서에도 문서화되어 있습니다.

  • %509s509 개의 공간을 생성합니다. 바이트 510까지 파일을 채워야합니다.

  • \125\2528 진수 == 0x55뒤에 0xaa.

    이들은 2 개의 필수 매직 바이트이며 바이트 511과 512 여야합니다.

    BIOS는 모든 디스크를 통해 부팅 가능한 디스크를 찾고, 두 개의 매직 바이트가있는 부팅 가능한 디스크 만 고려합니다.

    존재하지 않으면 하드웨어는이 디스크를 부팅 가능한 디스크로 취급하지 않습니다.

printf마스터 가 아닌 경우 다음을 사용 하여 내용을 확인할 수 있습니다 main.img.

hd main.img

예상되는 결과를 보여줍니다.

00000000  f4 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |.               |
00000010  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
*
000001f0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 55 aa  |              U.|
00000200

20ASCII의 공백은 어디에 있습니까 ?

BIOS 펌웨어는 디스크에서 512 바이트를 읽어 메모리에 저장 한 다음 PC를 첫 번째 바이트로 설정하여 실행을 시작합니다.

안녕하세요 세계 부팅 부문

최소한의 프로그램을 만들었으므로 이제 hello world로 넘어 갑시다.

분명한 질문은 IO를 수행하는 방법입니다. 몇 가지 옵션 :

  • 펌웨어를 요청하십시오 (예 : BIOS 또는 UEFI).

  • VGA : 쓰면 화면에 인쇄되는 특수 메모리 영역입니다. 보호 모드에서 사용할 수 있습니다.

  • 드라이버를 작성하고 디스플레이 하드웨어와 직접 대화하십시오. 이것은 "적절한"방법으로보다 강력하지만 복잡합니다.

  • 직렬 포트 . 이것은 호스트 터미널에서 문자를 보내고받는 매우 간단한 표준화 된 프로토콜입니다.

    데스크탑에서는 다음과 같습니다.

    여기에 이미지 설명을 입력하십시오

    소스 .

    불행히도 대부분의 최신 랩톱에는 노출되지 않지만 개발 보드를 사용하는 일반적인 방법입니다 (아래 ARM 예 참조).

    이러한 인터페이스는 예를 들어 Linux 커널을 디버깅하는 데 실제로 유용 하기 때문에 이것은 수치 입니다.

  • 칩의 디버그 기능을 사용하십시오. ARM은 예를 들어 세미 호스팅 을 호출합니다 . 실제 하드웨어에서는 추가 하드웨어 및 소프트웨어 지원이 필요하지만 에뮬레이터에서는 무료로 편리한 옵션이 될 수 있습니다. .

여기서는 x86에서 더 간단한 BIOS 예제를 수행 할 것입니다. 그러나 가장 강력한 방법은 아닙니다.

메인 .S

.code16
    mov $msg, %si
    mov $0x0e, %ah
loop:
    lodsb
    or %al, %al
    jz halt
    int $0x10
    jmp loop
halt:
    hlt
msg:
    .asciz "hello world"

GitHub의 상류 .

link.ld

SECTIONS
{
    /* The BIOS loads the code from the disk to this location.
     * We must tell that to the linker so that it can properly
     * calculate the addresses of symbols we might jump to.
     */
    . = 0x7c00;
    .text :
    {
        __start = .;
        *(.text)
        /* Place the magic boot bytes at the end of the first 512 sector. */
        . = 0x1FE;
        SHORT(0xAA55)
    }
}

조립 및 연결 :

as -g -o main.o main.S
ld --oformat binary -o main.img -T link.ld main.o
qemu-system-x86_64 -hda main.img

결과:

여기에 이미지 설명을 입력하십시오

그리고 T430에서 :

여기에 이미지 설명을 입력하십시오

테스트 대상 : Lenovo Thinkpad T430, UEFI BIOS 1.16. Ubuntu 18.04 호스트에서 생성 된 디스크.

표준 사용자 랜드 어셈블리 지침 외에도 다음과 같은 이점이 있습니다.

  • .code16: 16 비트 코드를 출력하도록 GAS에 지시

  • cli: 소프트웨어 인터럽트를 비활성화합니다. 그 후 프로세서가 다시 실행되기 시작할 수 있습니다.hlt

  • int $0x10: BIOS 호출을 수행합니다. 문자를 하나씩 인쇄합니다.

중요한 링크 플래그는 다음과 같습니다.

  • --oformat binary: 원시 이진 어셈블리 코드를 출력합니다. 일반 사용자 실행 파일의 경우와 같이 ELF 파일로 래핑하지 마십시오.

링커 스크립트 부분을 더 잘 이해하려면 연결의 재배치 단계를 숙지하십시오. 링커의 기능은 무엇입니까?

쿨러 x86 베어 메탈 프로그램

내가 달성 한 몇 가지 더 복잡한 베어 메탈 설정은 다음과 같습니다.

조립 대신 C 사용

요약 : GRUB 멀티 부트를 사용하면 생각하지 못한 많은 성가신 문제를 해결할 수 있습니다. 아래 섹션을 참조하십시오.

x86의 가장 큰 어려움은 BIOS가 디스크에서 메모리로 512 바이트 만로드하기 때문에 C를 사용할 때 512 바이트를 폭파시킬 수 있다는 것입니다!

이를 해결하기 위해 2 단계 부트 로더를 사용할 수 있습니다 . 그러면 디스크에서 메모리로 더 많은 바이트를로드하는 추가 BIOS 호출이 수행됩니다. 다음은 int 0x13 BIOS 호출을 사용하여 처음부터 최소 2 단계 어셈블리 예제입니다 .

또는

  • QEMU에서만 작동하지만 실제 하드웨어에서는 작동하지 않으면 -kernel전체 ELF 파일을 메모리에로드하는 옵션을 사용하십시오 . 이 방법으로 만든 ARM 예제는 다음과 같습니다 .
  • Raspberry Pi의 경우 기본 펌웨어는 kernel7.imgQEMU와 마찬가지로 ELF 파일에서 이미지 로딩을 처리합니다 -kernel.

교육 목적으로 만 사용되는 최소 C 예는 다음과 같습니다.

main.c

void main(void) {
    int i;
    char s[] = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
    for (i = 0; i < sizeof(s); ++i) {
        __asm__ (
            "int $0x10" : : "a" ((0x0e << 8) | s[i])
        );
    }
    while (1) {
        __asm__ ("hlt");
    };
}

항목 .S

.code16
.text
.global mystart
mystart:
    ljmp $0, $.setcs
.setcs:
    xor %ax, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %ss
    mov $__stack_top, %esp
    cld
    call main

linker.ld

ENTRY(mystart)
SECTIONS
{
  . = 0x7c00;
  .text : {
    entry.o(.text)
    *(.text)
    *(.data)
    *(.rodata)
    __bss_start = .;
    /* COMMON vs BSS: /programming/16835716/bss-vs-common-what-goes-where */
    *(.bss)
    *(COMMON)
    __bss_end = .;
  }
  /* /programming/53584666/why-does-gnu-ld-include-a-section-that-does-not-appear-in-the-linker-script */
  .sig : AT(ADDR(.text) + 512 - 2)
  {
      SHORT(0xaa55);
  }
  /DISCARD/ : {
    *(.eh_frame)
  }
  __stack_bottom = .;
  . = . + 0x1000;
  __stack_top = .;
}

운영

set -eux
as -ggdb3 --32 -o entry.o entry.S
gcc -c -ggdb3 -m16 -ffreestanding -fno-PIE -nostartfiles -nostdlib -o main.o -std=c99 main.c
ld -m elf_i386 -o main.elf -T linker.ld entry.o main.o
objcopy -O binary main.elf main.img
qemu-system-x86_64 -drive file=main.img,format=raw

C 표준 라이브러리

POSIX를 통해 C 표준 라이브러리 기능 많이 구현하는 Linux 커널이 없기 때문에 C 표준 라이브러리를 사용하려는 경우 상황이 더 재미있어집니다 .

Linux와 같은 본격적인 OS를 사용하지 않고 몇 가지 가능성은 다음과 같습니다.

  • 직접 작성하십시오. 결국 많은 헤더와 C 파일 일뿐입니다. 권리??

  • 뉴립

    자세한 예 : /electronics/223929/c-standard-libraries-on-bare-metal/223931

    NEWLIB 구현 당신을위한 모든 지루한 비-OS의 특정 것들, 예를 들어 memcmp, memcpy

    그런 다음, 필요한 syscall을 구현할 수있는 스텁을 제공합니다.

    예를 들어 다음 exit()과 같은 세미 호스팅을 통해 ARM에서 구현할 수 있습니다 .

    void _exit(int status) {
        __asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
    }
    

    이 예에 표시된대로 .

    예를 들어 printfUART 또는 ARM 시스템으로 리디렉션 하거나 semihosting으로 구현할 수 exit()있습니다 .

  • FreeRTOSZephyr 와 같은 임베디드 운영 체제 .

    이러한 운영 체제에서는 일반적으로 선제 적 스케줄링을 해제 할 수 있으므로 프로그램 실행 시간을 완전히 제어 할 수 있습니다.

    그것들은 일종의 사전 구현 된 Newlib로 볼 수 있습니다.

GNU GRUB 멀티 부트

부팅 섹터는 간단하지만 매우 편리하지는 않습니다.

  • 디스크 당 하나의 OS 만 가질 수 있습니다
  • 로드 코드는 실제로 작고 512 바이트에 맞아야합니다.
  • 보호 모드로 전환하는 등 많은 시작을 직접해야합니다

이런 이유로 GNU GRUB 은 multiboot라는보다 편리한 파일 형식을 만들었습니다.

최소 작업 예 : https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world

또한 GitHub 예제 리포지토리 에서 사용하여 USB를 백만 번 불 태우지 않고도 실제 하드웨어에서 모든 예제를 쉽게 실행할 수 있습니다.

QEMU 결과 :

여기에 이미지 설명을 입력하십시오

T430 :

여기에 이미지 설명을 입력하십시오

OS를 멀티 부팅 파일로 준비하면 GRUB은 일반 파일 시스템에서 OS를 찾을 수 있습니다.

이것이 대부분의 배포판에서하는 일이며 OS 이미지는 아래에 /boot있습니다.

멀티 부트 파일은 기본적으로 특수 헤더가있는 ELF 파일입니다. GRUB은 https://www.gnu.org/software/grub/manual/multiboot/multiboot.html 에서 지정합니다.

을 사용하여 멀티 부팅 파일을 부팅 가능한 디스크로 전환 할 수 있습니다 grub-mkrescue.

펌웨어

사실, 부트 섹터는 시스템의 CPU에서 실행되는 최초의 소프트웨어가 아닙니다.

실제로 가장 먼저 실행 되는 것은 소위 펌웨어 이며 소프트웨어입니다.

  • 하드웨어 제조업체가 만든
  • 일반적으로 비공개 소스이지만 아마도 C 기반
  • 읽기 전용 메모리에 저장되므로 공급 업체의 동의없이 수정하기가 어렵거나 불가능합니다.

잘 알려진 펌웨어는 다음과 같습니다.

  • BIOS : 기존의 모든 x86 펌웨어 SeaBIOS는 QEMU에서 사용하는 기본 오픈 소스 구현입니다.
  • UEFI : BIOS의 후속 버전으로,보다 표준화되었지만, 성능이 뛰어나고 엄청나게 부 풀었습니다.
  • Coreboot : 고귀한 크로스 아치 오픈 소스 시도

펌웨어는 다음과 같은 작업을 수행합니다.

  • 부팅 가능한 것을 찾을 때까지 각 하드 디스크, USB, 네트워크 등을 반복합니다.

    QEMU를 실행 하면 하드웨어에 연결된 하드 디스크 -hda라고 하며 처음 시도 main.img되는 하드 디스크 라고합니다 hda.

  • 처음 512 바이트를 RAM 메모리 주소에로드하고 0x7c00CPU의 RIP를 거기에 놓고 실행 시키십시오.

  • 부팅 메뉴 또는 BIOS 인쇄 호출과 같은 것을 디스플레이에 표시

펌웨어는 대부분의 OS가 의존하는 OS와 유사한 기능을 제공합니다. 예를 들어 Python 하위 세트가 BIOS / UEFI에서 실행되도록 포팅되었습니다 : https://www.youtube.com/watch?v=bYQ_lq5dcvM

펌웨어는 OS와 구별 할 수 없으며 펌웨어가 유일하게 할 수있는 유일한 "진정한"베어 메탈 프로그래밍이라고 주장 할 수 있습니다.

CoreOS 개발자는 다음과 같이 말합니다 .

어려운 부분

PC 전원을 켤 때 칩셋을 구성하는 칩 (northbridge, southbridge 및 SuperIO)이 아직 제대로 초기화되지 않았습니다. BIOS ROM이 가능한 한 CPU에서 제거되었지만 CPU가 액세스 할 수 있어야합니다. 그렇지 않으면 CPU가 실행할 명령이 없기 때문입니다. 그렇다고 BIOS ROM이 완전히 매핑 된 것은 아니며 일반적으로 그렇지 않습니다. 그러나 부팅 프로세스를 진행하기에 충분할만큼만 매핑됩니다. 다른 장치는 잊어 버리십시오.

QEMU에서 Coreboot를 실행하면 더 높은 계층의 Coreboot와 페이로드를 실험 할 수 있지만 QEMU는 낮은 수준의 시작 코드를 실험 할 기회가 거의 없습니다. 우선, RAM은 처음부터 바로 작동합니다.

BIOS 초기 상태

하드웨어의 많은 것들과 마찬가지로, 표준화는 약하고, 의존 하지 말아야 할 것 중 하나는 BIOS 이후에 코드가 실행되기 시작할 때 레지스터의 초기 상태입니다.

따라서 자신에게 호의를 베풀고 다음과 같은 초기화 코드를 사용 하십시오 . https://stackoverflow.com/a/32509555/895245

레지스터 는 중요한 부작용을 좋아 %ds하고 %es있으므로 명시 적으로 사용하지 않더라도 제로를 제거해야합니다.

일부 에뮬레이터는 실제 하드웨어보다 좋고 초기 상태가 좋습니다. 그런 다음 실제 하드웨어에서 실행하면 모든 것이 깨집니다.

엘 토리 토

CD에 구울 수있는 형식 : https://en.wikipedia.org/wiki/El_Torito_%28CD-ROM_standard%29

ISO 또는 USB에서 작동하는 하이브리드 이미지를 생성 할 수도 있습니다. 이것은 grub-mkrescue( )를 make isoimage사용하여 수행 할 수 있으며 Linux 커널을 사용하여 수행 할 수도 있습니다 isohybrid.

ARM에서는 일반적인 아이디어가 동일합니다.

IO에 사용할 BIOS와 같이 널리 사용 가능한 반 표준 사전 설치된 펌웨어가 없으므로 가장 간단한 두 가지 유형의 IO는 다음과 같습니다.

  • 시리얼, devboards에서 널리 이용 가능
  • LED를 깜박

나는 업로드했다 :

x86과의 차이점은 다음과 같습니다.

  • IO 직접 마법 주소를 작성하여 수행됩니다, 어떤이없는 inout지침을 제공합니다.

    이것을 메모리 매핑 된 IO 라고 합니다 .

  • Raspberry Pi와 같은 실제 하드웨어의 경우 디스크 이미지에 펌웨어 (BIOS)를 직접 추가 할 수 있습니다.

    펌웨어 업데이트가 더 투명 해지기 때문에 좋은 일입니다.

자원


3
유니 커널 은 너무 낮은 수준으로 가고 싶지 않고 여전히 발자국이 매우 적은 사람들을위한 대안입니다.
AndreLDM

1
@AndreLDM 나는 Linux 기반 Unikernel 뉴스를 추가하기 직전이지만 너무 초초 한 느낌이 들었습니다. next.redhat.com/2018/11/14/ukl-a-unikernel-based-on-linux
Ciro Santilli 郝海东 冠状 病六四 事件 法轮功

14
정말 자세한 답변이지만 "OS없이 실행되는 프로그램은 OS입니다"는 사실이 아닙니다. LED를 켜고 끄는 것만으로 OS를 만들지는 않는 프로그램을 작성할 수 있습니다. 플래시 드라이브에서 마이크로 컨트롤러를 실행하는 일부 펌웨어 코드는이를 OS로 만들지 않습니다. OS는 다른 소프트웨어를보다 쉽게 ​​작성할 수있는 최소한의 추상화 계층입니다. 요즘 최소한 스케줄러가 없다면 OS가 아닐 것입니다.
Vitali

4
OS에서 실행되지 않는 프로그램이 OS라는 절대 넌센스를 제외하고 좋은 대답입니다.
curiousdannii

3
@MichaelPetch 헤이, 부팅 섹터에 null을 저장하려면 :-) 그만한 가치가 없습니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3

영감으로 운영 체제

운영 체제는 프로그램입니다 우리는 또한 할 수 있도록 처음부터 작성 또는 변경하여 우리 자신의 프로그램을 만들 중 하나의 기능 (제한하거나 추가) 작은 운영 체제 , 다음 부팅 과정에서 실행 (AN 사용하여 ISO 이미지 ) .

예를 들어,이 페이지는 시작점으로 사용될 수 있습니다.

간단한 운영 체제를 작성하는 방법

여기서 전체 운영 체제는 512 바이트 부트 섹터 ( MBR ) 에 완전히 맞습니다 !

이러한 간단한 OS를 사용하면 다음과 같은 간단한 프레임 워크만들 수 있습니다 .

만들 RAM에 디스크의 부트 로더로드 이후 섹터 및 실행을 계속하려면 지점으로 이동 . 또는 플로피 드라이브에 사용되는 파일 시스템 인 FAT12를 읽고이를 구현할 수 있습니다.

그러나 많은 가능성이 있습니다. 예를 들어 더 큰 x86 어셈블리 언어 OS 를 보려면 간단한 16 비트 리얼 모드 OS 작업을 잘 설명 된 코드광범위한 문서 와 함께 보여주는 학습 도구 인 MykeOS x86 운영 체제를 살펴볼 수 있습니다 .

영감으로 부팅 로더

운영 체제없이 실행 되는 다른 일반적인 유형의 프로그램도 부트 로더 입니다. 예를 들어이 사이트를 사용하여 이러한 개념에서 영감을 얻은 프로그램을 만들 수 있습니다.

자신 만의 부트 로더를 개발하는 방법

위의 기사는 이러한 프로그램기본 아키텍처를 제시 합니다 .

  1. 0000 : 7C00 주소로 메모리에 올바르게로드하십시오.
  2. 고급 언어로 개발 된 BootMain 함수 호출
  3. 디스플레이에““Hello, world…”, low-level”메시지를 표시하십시오.

보다시피, 이 아키텍처는 매우 유연하며 반드시 부트 로더가 아닌 모든 프로그램을 구현할 수 있습니다 .

특히 "혼합 코드"기술 을 사용하는 방법을 보여줍니다. 덕분에 높은 수준의 구성 ( C 또는 C ++ ) 을 낮은 수준의 명령 ( Assembler )과 결합 할 수 있습니다. 이것은 매우 유용한 방법이지만 다음을 기억해야합니다.

프로그램을 빌드하고 실행 파일얻으려면 16 비트 모드 용 어셈블러의 컴파일러와 링커 가 필요 합니다 . C / C ++의 경우 16 비트 모드의 오브젝트 파일을 작성할 수 있는 컴파일러 만 필요 합니다 .

이 기사에서는 작성된 프로그램이 실제로 작동하는 방법과 테스트 및 디버그 수행 방법을 보여줍니다.

영감으로 UEFI 응용 프로그램

위의 예는 데이터 매체에 섹터 MBR을로드한다는 사실을 사용했습니다. 그러나 UEFI 응용 프로그램 을 사용하여 심도더 깊이 이해할 수 있습니다 .

OSFI를로드하는 것 외에도 UEFI는 EFI 시스템 파티션에 파일로있는 UEFI 응용 프로그램을 실행할 수 있습니다. UEFI 명령 셸, 펌웨어 부팅 관리자 또는 다른 UEFI 응용 프로그램에서 실행할 수 있습니다. UEFI 응용 프로그램은 시스템 제조업체와 독립적으로 개발 및 설치할 수 있습니다.

UEFI 응용 프로그램의 유형은 GRUB, rEFInd, Gummiboot 및 Windows Boot Manager와 같은 OS 로더입니다 . OS 파일을 메모리에로드하고 실행합니다. 또한 OS 로더는 다른 UEFI 응용 프로그램을 선택할 수 있도록 사용자 인터페이스를 제공 할 수 있습니다. UEFI 셸과 같은 유틸리티도 UEFI 응용 프로그램입니다.

우리가 원하는 경우 이러한 프로그램을 작성을 시작 , 우리는, 예를 들어,이 웹 사이트로 시작할 수 있습니다 :

EFI 프로그래밍 : "Hello, World"프로그램 만들기 / UEFI 프로그래밍-첫 단계

영감으로 보안 문제 탐색

운영 체제가 시작되기 전에 실행 되는 전체 악성 소프트웨어 그룹 (프로그램)이 있다는 것은 잘 알려져 있습니다.

이들 중 상당수는 위의 모든 솔루션과 마찬가지로 MBR 섹터 또는 UEFI 응용 프로그램에서 작동하지만 볼륨 부트 레코드 (VBR) 또는 BIOS 와 같은 다른 진입 점을 사용하는 것도 있습니다 .

알려진 4 가지 이상의 BIOS 공격 바이러스 가 있으며 그 중 2 개는 데모 용입니다.

아니면 다른 것도 있습니다.

시스템 시작 전 공격

부트 킷 은 Proof-of-Concept 개발에서 대량 배포로 발전했으며 이제는 사실상 오픈 소스 소프트웨어가되었습니다 .

부팅하는 다른 방법

또한 이러한 맥락에서이 있음을 언급 할 가치도 있다고 생각 이 있습니다 부팅 다양한 형태의 운영 체제 (또는 실행 프로그램이 대상이) . 이 많은,하지만 난에주의 싶습니다 네트워크에서 코드를로드에 네트워크 부팅 옵션 (사용하여 PXE를 우리가 컴퓨터에 프로그램을 실행 할 수 있습니다) 에 관계없이 운영 체제와도 상관없이 저장 매체 입니다 컴퓨터에 직접 연결

PXE (Network Booting) 란 무엇이며 어떻게 사용할 수 있습니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.