Jak samemu uruchomić program bez uruchomionego systemu operacyjnego? Czy można tworzyć programy asemblacyjne, które komputer może ładować i uruchamiać podczas uruchamiania, np. Uruchomić komputer z dysku flash i uruchamiać program na CPU?
Jak samemu uruchomić program bez uruchomionego systemu operacyjnego? Czy można tworzyć programy asemblacyjne, które komputer może ładować i uruchamiać podczas uruchamiania, np. Uruchomić komputer z dysku flash i uruchamiać program na CPU?
Odpowiedzi:
Jak samemu uruchomić program bez uruchomionego systemu operacyjnego?
Umieszczasz swój kod binarny w miejscu, w którym procesor szuka po ponownym uruchomieniu (np. Adres 0 na ARM).
Czy można tworzyć programy asemblacyjne, które komputer może ładować i uruchamiać podczas uruchamiania (np. Uruchomić komputer z dysku flash i uruchamia program znajdujący się na dysku)?
Ogólna odpowiedź na pytanie: można to zrobić. Często nazywane jest „programowaniem bez systemu metalowego”. Aby czytać z dysku flash, chcesz wiedzieć, co to jest USB i chcesz mieć sterownik do pracy z tym USB. Program na tym dysku musiałby również mieć określony format, na określonym systemie plików ... Jest to coś, co zwykle robią programy ładujące, ale twój program może zawierać własny program ładujący, więc jest samodzielny, jeśli oprogramowanie układowe będzie tylko załaduj mały blok kodu.
Wiele tablic ARM pozwala ci robić niektóre z tych rzeczy. Niektóre mają moduły ładujące, które pomagają w podstawowej konfiguracji.
Tutaj możesz znaleźć świetny samouczek na temat wykonywania podstawowego systemu operacyjnego na Raspberry Pi.
Edytuj: ten artykuł, a cała wiki.osdev.org odpowie na większość twoich pytań http://wiki.osdev.org/Introduction
Ponadto, jeśli nie chcesz eksperymentować bezpośrednio ze sprzętem, możesz uruchomić go jako maszynę wirtualną przy użyciu hiperwizorów, takich jak qemu. Zobacz, jak uruchomić „hello world” bezpośrednio na zwirtualizowanym sprzęcie ARM tutaj .
Przykłady możliwe do uruchomienia
Stwórzmy i uruchommy kilka maleńkich programów typu hello world, które działają bez systemu operacyjnego na:
Wypróbujemy je również na emulatorze QEMU w jak największym stopniu, ponieważ jest to bezpieczniejsze i wygodniejsze w rozwoju. Testy QEMU przeprowadzono na hoście Ubuntu 18.04 z wstępnie spakowanym pakietem QEMU 2.11.1.
Kod wszystkich przykładów x86 poniżej i więcej jest obecny w tym repozytorium GitHub .
Jak uruchomić przykłady na prawdziwym sprzęcie x86
Pamiętaj, że uruchamianie przykładów na prawdziwym sprzęcie może być niebezpieczne, np. Możesz przypadkowo wyczyścić dysk lub uszkodzić sprzęt: rób to tylko na starych komputerach, które nie zawierają krytycznych danych! Lub jeszcze lepiej, użyj tanich półprzezroczystych devboardów, takich jak Raspberry Pi, patrz przykład ARM poniżej.
W przypadku typowego laptopa x86 musisz zrobić coś takiego:
Wypal obraz na pendrivie (zniszczy twoje dane!):
sudo dd if=main.img of=/dev/sdX
podłącz USB do komputera
włącz to
powiedz, żeby uruchomił się z USB.
Oznacza to, że oprogramowanie układowe wybiera USB przed dyskiem twardym.
Jeśli nie jest to domyślne zachowanie twojego komputera, po włączeniu naciskaj Enter, F12, ESC lub inne takie dziwne klawisze, aż pojawi się menu rozruchu, w którym możesz wybrać rozruch z USB.
Często w tych menu można skonfigurować kolejność wyszukiwania.
Na przykład na moim T430 widzę następujące.
Po włączeniu muszę nacisnąć klawisz Enter, aby wejść do menu rozruchu:
Następnie tutaj muszę nacisnąć F12, aby wybrać USB jako urządzenie rozruchowe:
Stamtąd mogę wybrać USB jako urządzenie rozruchowe w następujący sposób:
Alternatywnie, aby zmienić kolejność rozruchu i wybrać USB, który ma wyższy priorytet, więc nie muszę go wybierać ręcznie za każdym razem, uderzyłbym F1 na ekranie „Menu przerwania uruchamiania”, a następnie nawiguję do:
Sektor rozruchowy
Na x86 najprostszym i najniższym poziomem, co możesz zrobić, jest utworzenie głównego sektora rozruchowego (MBR) , który jest rodzajem sektora rozruchowego , a następnie zainstalowanie go na dysku.
Tutaj tworzymy jedną za pomocą jednego printf
połączenia:
printf '\364%509s\125\252' > main.img
sudo apt-get install qemu-system-x86
qemu-system-x86_64 -hda main.img
Wynik:
Pamiętaj, że nawet bez robienia kilku znaków jest już wydrukowanych na ekranie. Są one drukowane przez oprogramowanie układowe i służą do identyfikacji systemu.
A na T430 dostajemy pusty ekran z migającym kursorem:
main.img
zawiera następujące elementy:
\364
in octal == 0xf4
in hex: kodowanie hlt
instrukcji, która każe CPU przestać działać.
Dlatego nasz program nic nie zrobi: wystarczy uruchomić i zatrzymać.
Używamy ósemki, ponieważ \x
liczby szesnastkowe nie są określone przez POSIX.
Możemy łatwo uzyskać to kodowanie za pomocą:
echo hlt > a.S
as -o a.o a.S
objdump -S a.o
które wyjścia:
a.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: f4 hlt
ale jest to również oczywiście udokumentowane w podręczniku Intela.
%509s
wyprodukuj 509 miejsc. Konieczne jest wypełnienie pliku do bajtu 510.
\125\252
ósemkowo ==, 0x55
po której następuje 0xaa
.
Są to 2 wymagane bajty magiczne, które muszą być bajtami 511 i 512.
BIOS przeszukuje wszystkie nasze dyski w poszukiwaniu dysków rozruchowych i bierze pod uwagę tylko te, które mają te dwa bajty.
Jeśli nie jest obecny, sprzęt nie będzie traktował tego jako dysku rozruchowego.
Jeśli nie jesteś printf
mistrzem, możesz potwierdzić zawartość za main.img
pomocą:
hd main.img
który pokazuje oczekiwane:
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
gdzie 20
jest spacja w ASCII.
Oprogramowanie układowe BIOS odczytuje te 512 bajtów z dysku, umieszcza je w pamięci i ustawia komputer na pierwszy bajt, aby rozpocząć ich wykonywanie.
Witaj, sektorze rozruchowym świata
Teraz, gdy stworzyliśmy minimalny program, przejdźmy do cześć świata.
Oczywiste pytanie brzmi: jak zrobić IO? Kilka opcji:
poprosić oprogramowanie wewnętrzne, np. BIOS lub UEFI, aby zrobiło to za nas
VGA: specjalny region pamięci, który zostanie wydrukowany na ekranie, jeśli zostanie zapisany. Może być używany w trybie chronionym.
napisz sterownik i porozmawiaj bezpośrednio ze sprzętem wyświetlającym. Jest to „właściwy” sposób na zrobienie tego: mocniejszy, ale bardziej złożony.
port szeregowy . Jest to bardzo prosty znormalizowany protokół, który wysyła i odbiera znaki z terminala hosta.
Na komputerach wygląda to tak:
Źródło .
Niestety nie jest narażony na większość współczesnych laptopów, ale jest powszechną drogą do tworzenia płyt deweloperskich, patrz przykłady ARM poniżej.
To naprawdę szkoda, ponieważ takie interfejsy są naprawdę przydatne na przykład do debugowania jądra Linuksa .
użyj funkcji debugowania układów. ARM na przykład nazywa ich semihosting . Na prawdziwym sprzęcie wymaga dodatkowej obsługi sprzętu i oprogramowania, ale na emulatorach może być bezpłatną wygodną opcją. Przykład .
Tutaj zrobimy przykład systemu BIOS, ponieważ jest on prostszy na x86. Pamiętaj jednak, że nie jest to najbardziej niezawodna metoda.
sieć elektryczna
.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)
}
}
Złóż i połącz z:
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
Wynik:
A na T430:
Testowane na: Lenovo Thinkpad T430, UEFI BIOS 1.16. Dysk wygenerowany na hoście Ubuntu 18.04.
Oprócz standardowych instrukcji montażu dla użytkownika, mamy:
.code16
: informuje GAS, aby wyprowadził 16-bitowy kod
cli
: wyłącz przerwania programowe. Mogą one spowodować, że procesor zacznie ponownie działać pohlt
int $0x10
: wykonuje połączenie BIOS. To właśnie drukuje znaki jeden po drugim.
Ważne flagi linków to:
--oformat binary
: wypisuje nieprzetworzony kod binarnego zestawu, nie zawijaj go w pliku ELF, jak ma to miejsce w przypadku zwykłych plików wykonywalnych dla użytkownika.Aby lepiej zrozumieć część skryptu linkera, zapoznaj się z krokiem relokacji linkowania: Co robią linkery?
Chłodniejsze programy x86 bez systemu metalowego
Oto kilka bardziej skomplikowanych ustawień bez systemu metalowego:
Użyj C zamiast montażu
Podsumowanie: użyj GRUB multiboot, który rozwiąże wiele irytujących problemów, o których nigdy nie pomyślałeś. Sekcja poniżej.
Główną trudnością na x86 jest to, że BIOS ładuje tylko 512 bajtów z dysku do pamięci, i możesz wysadzić te 512 bajtów podczas używania C!
Aby rozwiązać ten problem, możemy użyć dwustopniowego programu ładującego . Powoduje to kolejne wywołania systemu BIOS, które ładują więcej bajtów z dysku do pamięci. Oto minimalny przykład montażu etapu 2 od zera przy użyciu wywołań int 0x13 BIOS :
Alternatywnie:
-kernel
opcji, która ładuje cały plik ELF do pamięci. Oto przykład ARM, który utworzyłem tą metodą .kernel7.img
, podobnie jak -kernel
robi to QEMU .Tylko do celów edukacyjnych, oto przykładowy minimalny przykład C w jednym etapie :
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");
};
}
wejście 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 = .;
}
biegać
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
Biblioteka standardowa C.
Sprawa staje się jeszcze przyjemniejsza, jeśli chcesz również korzystać ze standardowej biblioteki C, ponieważ nie mamy jądra Linux, które implementuje większość standardowych funkcji biblioteki C za pośrednictwem POSIX .
Kilka możliwości, bez przechodzenia na w pełni funkcjonalny system operacyjny, taki jak Linux, to:
Napisz swoje własne. To tylko garść nagłówków i plików C, prawda? Dobrze??
Szczegółowy przykład na stronie : /electronics/223929/c-standard-libraries-on-bare-metal/223931
Newlib realizuje wszystkie rzeczy nudne non-OS specyficzne dla ciebie, na przykład memcmp
, memcpy
itd
Następnie udostępnia kilka kodów pośredniczących umożliwiających wdrożenie potrzebnych połączeń systemowych.
Na przykład możemy zaimplementować exit()
na ARM poprzez semihosting z:
void _exit(int status) {
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
}
jak pokazano w tym przykładzie .
Na przykład, można przekierować printf
do układów UART lub ARM, lub realizować exit()
z semihosting .
wbudowane systemy operacyjne, takie jak FreeRTOS i Zephyr .
Takie systemy operacyjne zazwyczaj umożliwiają wyłączenie planowania wyprzedzającego, co daje pełną kontrolę nad czasem działania programu.
Można je postrzegać jako rodzaj wstępnie wdrożonego Newlib.
GNU GRUB Multiboot
Sektory rozruchowe są proste, ale nie są zbyt wygodne:
Z tych powodów GNU GRUB stworzył wygodniejszy format pliku o nazwie multiboot.
Minimalny przykład działania: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world
Używam go również w moim repozytorium przykładów GitHub, aby móc z łatwością uruchamiać wszystkie przykłady na prawdziwym sprzęcie bez milionowego spalania USB.
Wynik QEMU:
T430:
Jeśli przygotujesz system operacyjny jako plik z wieloma uruchomieniami, GRUB będzie mógł go znaleźć w zwykłym systemie plików.
To właśnie robi większość dystrybucji, umieszczając obrazy systemu operacyjnego /boot
.
Pliki Multiboot są w zasadzie plikiem ELF ze specjalnym nagłówkiem. Są one określone przez GRUB pod adresem : https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
Możesz zmienić plik z wieloma uruchomieniami na dysk rozruchowy za pomocą grub-mkrescue
.
Oprogramowanie układowe
W rzeczywistości sektor rozruchowy nie jest pierwszym oprogramowaniem działającym na procesorze systemu.
Najpierw uruchamia się tak zwane oprogramowanie układowe , które jest oprogramowaniem:
Dobrze znane oprogramowanie wewnętrzne obejmuje:
Oprogramowanie wewnętrzne wykonuje następujące czynności:
zapętlaj każdy dysk twardy, USB, sieć itp., aż znajdziesz coś rozruchowego.
Kiedy uruchamiamy QEMU, -hda
mówi, że main.img
jest to dysk twardy podłączony do sprzętu i hda
jest pierwszym, który zostanie wypróbowany i jest używany.
załaduj pierwsze 512 bajtów na adres pamięci RAM 0x7c00
, umieść tam RIP procesora i pozwól mu działać
pokaż na ekranie takie menu, jak menu uruchamiania lub wywołania drukowania systemu BIOS
Oprogramowanie układowe oferuje funkcje podobne do systemu operacyjnego, od których zależy większość systemów operacyjnych. Np. Podzestaw Python został przeniesiony do działania w systemie BIOS / UEFI: https://www.youtube.com/watch?v=bYQ_lq5dcvM
Można argumentować, że oprogramowanie układowe jest nierozróżnialne od systemów operacyjnych i że oprogramowanie układowe jest jedynym „prawdziwym” programowaniem bez systemu operacyjnego.
Jak to ujął to deweloper CoreOS :
Trudna część
Po włączeniu komputera układy scalone (mostek północny, mostek południowy i SuperIO) nie są jeszcze poprawnie zainicjowane. Chociaż pamięć ROM systemu BIOS jest tak daleko od procesora, jak to tylko możliwe, jest ona dostępna dla procesora, ponieważ musi być, w przeciwnym razie procesor nie miałby instrukcji do wykonania. Nie oznacza to, że BIOS ROM jest całkowicie zmapowany, zwykle nie. Ale tylko tyle jest zmapowane, aby rozpocząć proces rozruchu. Wszelkie inne urządzenia, po prostu zapomnij.
Po uruchomieniu Coreboot w QEMU możesz eksperymentować z wyższymi warstwami Coreboot i ładunkami, ale QEMU oferuje niewiele możliwości eksperymentowania z kodem startowym niskiego poziomu. Po pierwsze, pamięć RAM działa od samego początku.
Stan początkowy po BIOS
Podobnie jak wiele rzeczy w sprzęcie, standaryzacja jest słaba, a jedną z rzeczy, na których nie należy polegać, jest stan początkowy rejestrów, gdy kod zaczyna działać po BIOS.
Więc zrób sobie przysługę i użyj kodu inicjalizacji, takiego jak: https://stackoverflow.com/a/32509555/895245
Rejestruje się %ds
i %es
ma ważne skutki uboczne, więc powinieneś je wyzerować, nawet jeśli nie używasz ich wyraźnie.
Zauważ, że niektóre emulatory są ładniejsze niż prawdziwy sprzęt i zapewniają dobry stan początkowy. Potem, gdy idziesz na prawdziwym sprzęcie, wszystko się psuje.
El Torito
Format, który można wypalić na płytach CD: https://en.wikipedia.org/wiki/El_Torito_%28CD-ROM_standard%29
Możliwe jest również wytworzenie obrazu hybrydowego działającego na ISO lub USB. Można to zrobić za pomocą grub-mkrescue
( przykład ), a także przy make isoimage
użyciu jądra Linux isohybrid
.
RAMIĘ
W ARM ogólne pomysły są takie same.
Nie ma powszechnie dostępnego, częściowo znormalizowanego, wstępnie zainstalowanego oprogramowania układowego, takiego jak BIOS, do użycia dla IO, więc dwa najprostsze typy IO, które możemy wykonać to:
Przesłałem:
kilka prostych QEMU C + Newlib i surowe przykłady montażu tutaj na GitHub .
Na przykład prompt.c pobiera dane wejściowe z terminala hosta i zwraca dane wyjściowe za pośrednictwem symulowanego 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
Zobacz także: Jak tworzyć programy ARM typu bare metal i uruchamiać je na QEMU?
w pełni zautomatyzowana konfiguracja migacza Raspberry Pi pod adresem : https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker
Zobacz także: Jak uruchomić program C bez systemu operacyjnego na Raspberry Pi?
Aby „zobaczyć” diody LED na QEMU, musisz skompilować QEMU ze źródła z flagą debugowania: /raspberrypi/56373/is-it-possible-to-get-the-state-of- the-leds-and-gpios-in-a-qemu-emulation-like-t
Następnie powinieneś wypróbować cześć świata UART. Możesz zacząć od przykładu migacza i zastąpić jądro tym: https://github.com/dwelch67/raspberrypi/tree/bce377230c2cdd8ff1e40919fdedbc2533ef5a00/uart01
Najpierw poproś UART o pracę z Raspbian, jak wyjaśniłem na: /raspberrypi/38/prepare-for-ssh-woutout-a-screen/54394#54394 Będzie to wyglądało mniej więcej tak:
Upewnij się, że używasz odpowiednich pinów, w przeciwnym razie możesz spalić konwerter UART na USB. Zrobiłem to już dwa razy, powodując zwarcie do masy i 5 V ...
Na koniec połącz się z komputerem szeregowym za pomocą:
screen /dev/ttyUSB0 115200
W przypadku Raspberry Pi używamy karty Micro SD zamiast pamięci USB do przechowywania naszego pliku wykonywalnego, do którego zwykle potrzebujesz adaptera do połączenia z komputerem:
Nie zapomnij odblokować adaptera SD, jak pokazano na stronie : /ubuntu/213889/microsd-card-is-set-to-read-only-state-how-can-i-write-data -on-it / 814585 # 814585
https://github.com/dwelch67/raspberrypi wygląda jak najpopularniejszy dostępny obecnie samouczek Raspberry Pi od zera.
Niektóre różnice w stosunku do x86 obejmują:
IO odbywa się poprzez bezpośrednie pisanie na magiczne adresy, nie ma instrukcji in
i out
instrukcji.
Nazywa się to We / Wy mapowanym na pamięć .
w przypadku niektórych prawdziwych urządzeń, takich jak Raspberry Pi, możesz samodzielnie dodać oprogramowanie układowe (BIOS) do obrazu dysku.
To dobrze, ponieważ sprawia, że aktualizacja tego oprogramowania jest bardziej przejrzysta.
Zasoby
System operacyjny jest także programem , więc możemy również stworzyć własny program, tworząc od podstaw lub zmieniając (ograniczając lub dodając) funkcje jednego z małych systemów operacyjnych , a następnie uruchamiając go podczas procesu rozruchu (przy użyciu obrazu ISO ) .
Na przykład tę stronę można wykorzystać jako punkt wyjścia:
Jak napisać prosty system operacyjny
Tutaj cały system operacyjny mieści się całkowicie w 512-bajtowym sektorze rozruchowym ( MBR )!
Taki lub podobny prosty system operacyjny może być wykorzystany do stworzenia prostej struktury, która pozwoli nam:
spraw, by bootloader ładował kolejne sektory z dysku do pamięci RAM i przeskoczył do tego punktu, aby kontynuować wykonywanie . Lub możesz przeczytać na FAT12, systemie plików używanym na dyskietkach i zaimplementować to .
Istnieje jednak wiele możliwości. Na przykład, aby zobaczyć większy system operacyjny w języku asemblera x86 , możemy zapoznać się z systemem operacyjnym MykeOS , x86, który jest narzędziem do nauki pokazującym proste 16-bitowe działanie systemów operacyjnych w trybie rzeczywistym, z dobrze skomentowanym kodem i obszerną dokumentacją .
Inne popularne typy programów, które działają bez systemu operacyjnego, to także programy ładujące rozruch . Możemy stworzyć program inspirowany taką koncepcją, na przykład korzystając z tej strony:
Jak opracować własny moduł ładujący
Powyższy artykuł przedstawia także podstawową architekturę takich programów :
- Prawidłowe ładowanie do pamięci o 0000: 7C00.
- Wywołanie funkcji BootMain opracowanej w języku wysokiego poziomu.
- Pokaż komunikat „” Witaj, świecie… ”z niskiego poziomu” na wyświetlaczu.
Jak widzimy, ta architektura jest bardzo elastyczna i pozwala nam na implementację dowolnego programu , niekoniecznie programu ładującego.
W szczególności pokazuje, jak stosować technikę „kodu mieszanego”, dzięki której można łączyć konstrukcje wysokiego poziomu (z C lub C ++ ) z poleceniami niskiego poziomu (z asemblera ). Jest to bardzo przydatna metoda, ale musimy pamiętać, że:
aby zbudować program i uzyskać plik wykonywalny , będziesz potrzebował kompilatora i linkera Assemblera dla trybu 16-bitowego . W przypadku C / C ++ potrzebujesz tylko kompilatora, który może tworzyć pliki obiektowe dla trybu 16-bitowego .
Artykuł pokazuje także, jak zobaczyć stworzony program w akcji oraz jak przeprowadzić jego testowanie i debugowanie.
W powyższych przykładach wykorzystano fakt ładowania MBR sektora na nośnik danych. Możemy jednak zagłębić się w otchłań , grając na przykład w aplikacjach UEFI :
Oprócz ładowania systemu operacyjnego UEFI może uruchamiać aplikacje UEFI, które znajdują się jako pliki na partycji systemowej EFI. Można je wykonać z powłoki poleceń UEFI, menedżera rozruchowego oprogramowania układowego lub innych aplikacji UEFI. Aplikacje UEFI można opracowywać i instalować niezależnie od producenta systemu.
Typem aplikacji UEFI jest moduł ładujący system operacyjny, taki jak GRUB, rEFInd, Gummiboot i Windows Boot Manager; który ładuje plik systemu operacyjnego do pamięci i wykonuje go. Ponadto moduł ładujący system operacyjny może zapewnić interfejs użytkownika, który umożliwia wybór innej aplikacji UEFI do uruchomienia. Narzędzia takie jak powłoka UEFI są również aplikacjami UEFI.
Jeśli chcielibyśmy zacząć tworzyć takie programy , możemy na przykład zacząć od tych stron internetowych:
Programowanie dla EFI: tworzenie programu „Hello, World” / Programowanie UEFI - pierwsze kroki
Powszechnie wiadomo, że istnieje cała grupa złośliwego oprogramowania przed uruchomieniem systemu operacyjnego działa (które są programami) .
Ogromna grupa z nich działa w sektorze MBR lub aplikacjach UEFI, podobnie jak wszystkie powyższe rozwiązania, ale są też takie, które wykorzystują inny punkt wejścia, taki jak Volume Boot Record (VBR) lub BIOS :
Istnieją co najmniej cztery znane wirusy atakujące BIOS , z których dwa były przeznaczone do celów demonstracyjnych.
a może jeszcze jeden.
Ataki przed uruchomieniem systemu
Bootkity ewoluowały od rozwoju Proof-of-Concept do dystrybucji masowej i teraz skutecznie stają się oprogramowaniem typu open source .
Myślę również, że w tym kontekście warto również wspomnieć, że istnieją różne formy uruchamiania systemu operacyjnego (lub przeznaczonego do tego programu wykonywalnego) . Istnieje wiele, ale chciałbym zwrócić uwagę na ładowanie kodu z sieci za pomocą opcji rozruchu sieciowego ( PXE ), która pozwala nam uruchamiać program na komputerze niezależnie od systemu operacyjnego, a nawet niezależnie od dowolnego nośnika pamięci, który jest bezpośrednio podłączony do komputera:
Co to jest ładowanie sieciowe (PXE) i jak z niego korzystać?