운영 체제를 실행하지 않고 어떻게 프로그램을 자체적으로 실행합니까? 컴퓨터를 시작할 때로드하고 실행할 수있는 어셈블리 프로그램을 만들 수 있습니까 (예 : 플래시 드라이브에서 컴퓨터를 부팅하고 CPU에있는 프로그램을 실행)?
운영 체제를 실행하지 않고 어떻게 프로그램을 자체적으로 실행합니까? 컴퓨터를 시작할 때로드하고 실행할 수있는 어셈블리 프로그램을 만들 수 있습니까 (예 : 플래시 드라이브에서 컴퓨터를 부팅하고 CPU에있는 프로그램을 실행)?
답변:
운영 체제를 실행하지 않고 어떻게 프로그램을 자체적으로 실행합니까?
이진 코드는 재부팅 후 프로세서가 찾는 위치 (예 : ARM의 주소 0)에 배치합니다.
컴퓨터를 시작할 때로드하고 실행할 수있는 어셈블리 프로그램을 만들 수 있습니까 (예 : 플래시 드라이브에서 컴퓨터를 부팅하고 드라이브에있는 프로그램을 실행)?
질문에 대한 일반적인 답변 : 할 수 있습니다. 종종 "베어 메탈 프로그래밍"이라고합니다. 플래시 드라이브에서 읽으려면 USB가 무엇인지 알고 싶어서이 USB와 작동하는 드라이버가 필요합니다. 이 드라이브의 프로그램은 특정 파일 시스템의 특정 형식이어야합니다. 이것은 부트 로더가 일반적으로하는 작업이지만 프로그램에 자체 부트 로더가 포함되어 있으므로 펌웨어 만 작은 코드 블록을로드하십시오.
많은 ARM 보드에서 이러한 작업을 수행 할 수 있습니다. 일부에는 기본 설정을 도와주는 부트 로더가 있습니다.
여기 에서는 Raspberry Pi에서 기본 운영 체제를 수행하는 방법에 대한 훌륭한 자습서를 찾을 수 있습니다.
편집 :이 기사와 전체 wiki.osdev.org는 대부분의 질문에 답합니다 http://wiki.osdev.org/Introduction
또한 하드웨어를 직접 실험하지 않으려는 경우 qemu와 같은 하이퍼 바이저를 사용하여 가상 머신으로 실행할 수 있습니다. 가상화 된 ARM 하드웨어 에서 직접 "hello world"를 실행하는 방법은 여기를 참조하십시오 .
실행 가능한 예제
OS없이 실행되는 몇 가지 미처리 베어 메탈 Hello World 프로그램을 작성하고 실행 해 보겠습니다.
또한 QEMU 에뮬레이터에서 최대한 안전하고 개발하기 편리하도록 시험해 볼 것입니다. QEMU 테스트는 사전 패키지 된 QEMU 2.11.1과 함께 Ubuntu 18.04 호스트에서 수행되었습니다.
아래의 모든 x86 예제 코드는 이 GitHub 리포지토리에 있습니다.
x86 실제 하드웨어에서 예제를 실행하는 방법
실제 하드웨어에서 예제를 실행하는 것은 위험 할 수 있습니다. 예를 들어 실수로 디스크를 지우거나 하드웨어를 손상시킬 수 있습니다. 중요한 데이터가 포함되지 않은 오래된 시스템에서만이 작업을 수행하십시오! 또는 Raspberry Pi와 같은 저렴한 반 일회용 보드를 사용하십시오 (아래 ARM 예 참조).
일반적인 x86 랩톱의 경우 다음과 같은 작업을 수행해야합니다.
이미지를 USB 스틱에 굽습니다 (데이터가 손상 될 수 있습니다).
sudo dd if=main.img of=/dev/sdX
컴퓨터에 USB를 연결
전원을 켜십시오
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
다음을 포함합니다 :
\364
8 진수 == 0xf4
16 진수 : hlt
명령어 인코딩으로 CPU가 작동을 중지하도록 지시합니다.
따라서 우리의 프로그램은 아무것도하지 않을 것입니다 : 시작과 중지 만.
\x
POSIX에서 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
물론 인텔 설명서에도 문서화되어 있습니다.
%509s
509 개의 공간을 생성합니다. 바이트 510까지 파일을 채워야합니다.
\125\252
8 진수 == 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
20
ASCII의 공백은 어디에 있습니까 ?
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"
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 단계 어셈블리 예제입니다 .
또는
-kernel
전체 ELF 파일을 메모리에로드하는 옵션을 사용하십시오 . 이 방법으로 만든 ARM 예제는 다음과 같습니다 .kernel7.img
QEMU와 마찬가지로 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");
}
이 예에 표시된대로 .
예를 들어 printf
UART 또는 ARM 시스템으로 리디렉션 하거나 semihosting으로 구현할 수 exit()
있습니다 .
FreeRTOS 및 Zephyr 와 같은 임베디드 운영 체제 .
이러한 운영 체제에서는 일반적으로 선제 적 스케줄링을 해제 할 수 있으므로 프로그램 실행 시간을 완전히 제어 할 수 있습니다.
그것들은 일종의 사전 구현 된 Newlib로 볼 수 있습니다.
GNU GRUB 멀티 부트
부팅 섹터는 간단하지만 매우 편리하지는 않습니다.
이런 이유로 GNU GRUB 은 multiboot라는보다 편리한 파일 형식을 만들었습니다.
또한 GitHub 예제 리포지토리 에서 사용하여 USB를 백만 번 불 태우지 않고도 실제 하드웨어에서 모든 예제를 쉽게 실행할 수 있습니다.
QEMU 결과 :
T430 :
OS를 멀티 부팅 파일로 준비하면 GRUB은 일반 파일 시스템에서 OS를 찾을 수 있습니다.
이것이 대부분의 배포판에서하는 일이며 OS 이미지는 아래에 /boot
있습니다.
멀티 부트 파일은 기본적으로 특수 헤더가있는 ELF 파일입니다. GRUB은 https://www.gnu.org/software/grub/manual/multiboot/multiboot.html 에서 지정합니다.
을 사용하여 멀티 부팅 파일을 부팅 가능한 디스크로 전환 할 수 있습니다 grub-mkrescue
.
펌웨어
사실, 부트 섹터는 시스템의 CPU에서 실행되는 최초의 소프트웨어가 아닙니다.
실제로 가장 먼저 실행 되는 것은 소위 펌웨어 이며 소프트웨어입니다.
잘 알려진 펌웨어는 다음과 같습니다.
펌웨어는 다음과 같은 작업을 수행합니다.
부팅 가능한 것을 찾을 때까지 각 하드 디스크, USB, 네트워크 등을 반복합니다.
QEMU를 실행 하면 하드웨어에 연결된 하드 디스크 -hda
라고 하며 처음 시도 main.img
되는 하드 디스크 라고합니다 hda
.
처음 512 바이트를 RAM 메모리 주소에로드하고 0x7c00
CPU의 RIP를 거기에 놓고 실행 시키십시오.
부팅 메뉴 또는 BIOS 인쇄 호출과 같은 것을 디스플레이에 표시
펌웨어는 대부분의 OS가 의존하는 OS와 유사한 기능을 제공합니다. 예를 들어 Python 하위 세트가 BIOS / UEFI에서 실행되도록 포팅되었습니다 : https://www.youtube.com/watch?v=bYQ_lq5dcvM
펌웨어는 OS와 구별 할 수 없으며 펌웨어가 유일하게 할 수있는 유일한 "진정한"베어 메탈 프로그래밍이라고 주장 할 수 있습니다.
어려운 부분
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는 다음과 같습니다.
나는 업로드했다 :
GitHub 의 몇 가지 간단한 QEMU C + Newlib 및 원시 어셈블리 예제 입니다.
prompt.c 예 예는 호스트 단말로부터 입력을 받아 모든 UART 시뮬레이션을 통해 다시 출력을 제공한다 :
enter a character
got: a
new alloc of 1 bytes at address 0x0x4000a1c0
enter a character
got: b
new alloc of 2 bytes at address 0x0x4000a1c0
enter a character
베어 메탈 ARM 프로그램을 만들고 QEMU에서 실행하는 방법 도 참조하십시오 .
https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker 에서 완전 자동화 된 Raspberry Pi 깜박임 설정
참고 : Raspberry Pi에서 OS없이 C 프로그램을 실행하는 방법?
QEMU의 LED를 "보려면"디버그 플래그를 사용하여 소스에서 QEMU를 컴파일해야합니다. /raspberrypi/56373/is-it-possible-to-get-the-state-of- Qedmu 에뮬레이션과 같은 T 주도 및 GPIOS
다음으로 UART hello world를 시도해야합니다. 깜박임 예제에서 시작하여 커널을 다음과 같이 바꿀 수 있습니다 : https://github.com/dwelch67/raspberrypi/tree/bce377230c2cdd8ff1e40919fdedbc2533ef5a00/uart01
먼저 /raspberrypi/38/prepare-for-ssh-without-a-screen/54394#54394 에서 설명한대로 UART를 Raspbian과 함께 사용 하십시오.
올바른 핀을 사용하십시오. 그렇지 않으면 UART to USB 변환기를 구울 수 있습니다. 단락 접지와 5V로 이미 두 번 수행했습니다 ...
마지막으로 다음을 사용하여 호스트에서 직렬에 연결하십시오.
screen /dev/ttyUSB0 115200
Raspberry Pi의 경우 USB 스틱 대신 Micro SD 카드를 사용하여 실행 파일을 포함합니다. 일반적으로 컴퓨터에 연결하려면 어댑터가 필요합니다.
/ubuntu/213889/microsd-card-is-set-to-read-only-state-how-can-i-write-data에 표시된대로 SD 어댑터를 잠금 해제하는 것을 잊지 마십시오. -on-it / 814585 # 814585
https://github.com/dwelch67/raspberrypi 는 오늘날 가장 인기있는 베어 메탈 라즈베리 파이 튜토리얼처럼 보입니다.
x86과의 차이점은 다음과 같습니다.
IO 직접 마법 주소를 작성하여 수행됩니다, 어떤이없는 in
및 out
지침을 제공합니다.
이것을 메모리 매핑 된 IO 라고 합니다 .
Raspberry Pi와 같은 실제 하드웨어의 경우 디스크 이미지에 펌웨어 (BIOS)를 직접 추가 할 수 있습니다.
펌웨어 업데이트가 더 투명 해지기 때문에 좋은 일입니다.
자원
운영 체제는 프로그램입니다 우리는 또한 할 수 있도록 처음부터 작성 또는 변경하여 우리 자신의 프로그램을 만들 중 하나의 기능 (제한하거나 추가) 작은 운영 체제 , 다음 부팅 과정에서 실행 (AN 사용하여 ISO 이미지 ) .
예를 들어,이 페이지는 시작점으로 사용될 수 있습니다.
여기서 전체 운영 체제는 512 바이트 부트 섹터 ( MBR ) 에 완전히 맞습니다 !
이러한 간단한 OS를 사용하면 다음과 같은 간단한 프레임 워크 를 만들 수 있습니다 .
만들 RAM에 디스크의 부트 로더로드 이후 섹터 및 실행을 계속하려면 지점으로 이동 . 또는 플로피 드라이브에 사용되는 파일 시스템 인 FAT12를 읽고이를 구현할 수 있습니다.
그러나 많은 가능성이 있습니다. 예를 들어 더 큰 x86 어셈블리 언어 OS 를 보려면 간단한 16 비트 리얼 모드 OS 작업을 잘 설명 된 코드 와 광범위한 문서 와 함께 보여주는 학습 도구 인 MykeOS x86 운영 체제를 살펴볼 수 있습니다 .
운영 체제없이 실행 되는 다른 일반적인 유형의 프로그램도 부트 로더 입니다. 예를 들어이 사이트를 사용하여 이러한 개념에서 영감을 얻은 프로그램을 만들 수 있습니다.
위의 기사는 이러한 프로그램 의 기본 아키텍처를 제시 합니다 .
- 0000 : 7C00 주소로 메모리에 올바르게로드하십시오.
- 고급 언어로 개발 된 BootMain 함수 호출
- 디스플레이에““Hello, world…”, low-level”메시지를 표시하십시오.
보다시피, 이 아키텍처는 매우 유연하며 반드시 부트 로더가 아닌 모든 프로그램을 구현할 수 있습니다 .
특히 "혼합 코드"기술 을 사용하는 방법을 보여줍니다. 덕분에 높은 수준의 구성 ( C 또는 C ++ ) 을 낮은 수준의 명령 ( Assembler )과 결합 할 수 있습니다. 이것은 매우 유용한 방법이지만 다음을 기억해야합니다.
프로그램을 빌드하고 실행 파일 을 얻으려면 16 비트 모드 용 어셈블러의 컴파일러와 링커 가 필요 합니다 . C / C ++의 경우 16 비트 모드의 오브젝트 파일을 작성할 수 있는 컴파일러 만 필요 합니다 .
이 기사에서는 작성된 프로그램이 실제로 작동하는 방법과 테스트 및 디버그 수행 방법을 보여줍니다.
위의 예는 데이터 매체에 섹터 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를 우리가 컴퓨터에 프로그램을 실행 할 수 있습니다) 에 관계없이 운영 체제와도 상관없이 저장 매체 입니다 컴퓨터에 직접 연결