Como executar um programa sem um sistema operacional?

239

Como você executa um programa sozinho sem um sistema operacional em execução? Você pode criar programas de montagem que o computador possa carregar e executar na inicialização, por exemplo, inicializar o computador a partir de uma unidade flash e executar o programa que está na CPU?

user2320609
fonte
4
Em qual arquitetura? x86? BRAÇO?
Kissiel
1
Eu estava falando de maneira geral, mas provavelmente x86 ou x64
#
2
Sim, é exatamente assim que os processadores são inicializados. não precisa ser montado, C é frequentemente usado com um pouco de asm para um bootstrap e talvez algum outro suporte.
26614 Old_timer
23
Pense nisso: se não houvesse essa capacidade, como o próprio sistema operacional seria iniciado e executado? :)
Seva Alekseyev

Respostas:

153

Como você executa um programa sozinho sem um sistema operacional em execução?

Você coloca seu código binário em um local onde o processador procura após a reinicialização (por exemplo, endereço 0 no ARM).

Você pode criar programas de montagem que o computador possa carregar e executar na inicialização (por exemplo, inicialize o computador a partir de uma unidade flash e execute o programa que está na unidade)?

Resposta geral à pergunta: isso pode ser feito. É freqüentemente chamado de "programação bare metal". Para ler a partir da unidade flash, você quer saber o que é USB e deseja ter algum driver para trabalhar com este USB. O programa nesta unidade também teria que estar em algum formato específico, em algum sistema de arquivos específico ... Isso é algo que os carregadores de inicialização geralmente fazem, mas seu programa pode incluir seu próprio carregador de inicialização, para que seja independente, se o firmware for apenas carregue um pequeno bloco de código.

Muitas placas ARM permitem fazer algumas dessas coisas. Alguns possuem gerenciadores de inicialização para ajudá-lo com a configuração básica.

Aqui você pode encontrar um ótimo tutorial sobre como fazer um sistema operacional básico em um Raspberry Pi.

Edit: Este artigo, e todo o wiki.osdev.org responderão à maioria das suas perguntas http://wiki.osdev.org/Introduction

Além disso, se você não quiser experimentar diretamente no hardware, poderá executá-lo como uma máquina virtual usando hipervisores como o qemu. Veja como executar o "hello world" diretamente no hardware ARM virtualizado aqui .

Kissiel
fonte
722

Exemplos executáveis

Vamos criar e executar alguns minúsculos programas hello world do bare metal que são executados sem um sistema operacional:

Também os testaremos no emulador QEMU, tanto quanto possível, pois é mais seguro e conveniente para o desenvolvimento. Os testes do QEMU foram realizados em um host Ubuntu 18.04 com o QEMU 2.11.1 pré-empacotado.

O código de todos os exemplos x86 abaixo e mais está presente neste repositório do GitHub .

Como executar os exemplos no hardware real x86

Lembre-se de que exemplos em execução em hardware real podem ser perigosos, por exemplo, você pode limpar seu disco ou bloquear o hardware por engano: faça isso apenas em máquinas antigas que não contêm dados críticos! Ou melhor ainda, use devboards semi-descartáveis ​​baratos, como o Raspberry Pi, veja o exemplo do ARM abaixo.

Para um laptop x86 típico, é necessário fazer algo como:

  1. Grave a imagem em um pen drive (destruirá seus dados!):

    sudo dd if=main.img of=/dev/sdX
    
  2. conecte o USB ao computador

  3. ligue

  4. diga para inicializar a partir do USB.

    Isso significa fazer com que o firmware escolha USB antes do disco rígido.

    Se esse não é o comportamento padrão da sua máquina, continue pressionando Enter, F12, ESC ou outras teclas estranhas após a inicialização, até que você obtenha um menu de inicialização onde você pode selecionar para inicializar a partir do USB.

    Geralmente, é possível configurar a ordem de pesquisa nesses menus.

Por exemplo, no meu T430, vejo o seguinte.

Depois de ligar, é quando eu tenho que pressionar Enter para entrar no menu de inicialização:

insira a descrição da imagem aqui

Então, aqui eu tenho que pressionar F12 para selecionar o USB como o dispositivo de inicialização:

insira a descrição da imagem aqui

A partir daí, posso selecionar o USB como o dispositivo de inicialização assim:

insira a descrição da imagem aqui

Como alternativa, para alterar a ordem de inicialização e escolher o USB com maior precedência, para que eu não precise selecioná-lo manualmente todas as vezes, pressione F1 na tela "Menu de interrupção de inicialização" e navegue até:

insira a descrição da imagem aqui

Setor de inicialização

No x86, a coisa mais simples e de nível mais baixo que você pode fazer é criar um MBR (setor de inicialização mestre) , que é um tipo de setor de inicialização , e depois instalá-lo em um disco.

Aqui, criamos um com uma única printfchamada:

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

Resultado:

insira a descrição da imagem aqui

Observe que, mesmo sem fazer nada, alguns caracteres já estão impressos na tela. Esses são impressos pelo firmware e servem para identificar o sistema.

E no T430, obtemos uma tela em branco com um cursor piscando:

insira a descrição da imagem aqui

main.img contém o seguinte:

  • \364in octal == 0xf4in hex: a codificação de uma hltinstrução, que diz à CPU para parar de funcionar.

    Portanto, nosso programa não fará nada: apenas inicie e pare.

    Usamos octal porque os \xnúmeros hexadecimais não são especificados pelo POSIX.

    Poderíamos obter essa codificação facilmente com:

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

    quais saídas:

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

    mas também está documentado no manual da Intel, é claro.

  • %509sproduzir 509 espaços. Necessário preencher o arquivo até o byte 510.

  • \125\252em octal == 0x55seguido por 0xaa.

    Estes são 2 bytes mágicos necessários, que devem ser os bytes 511 e 512.

    O BIOS passa por todos os nossos discos procurando por inicializáveis, e considera apenas inicializáveis ​​aqueles que possuem esses dois bytes mágicos.

    Se não estiver presente, o hardware não tratará isso como um disco inicializável.

Se você não é um printfmestre, pode confirmar o conteúdo main.imgcom:

hd main.img

que mostra o esperado:

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

onde 20é um espaço em ASCII.

O firmware do BIOS lê esses 512 bytes do disco, coloca-os na memória e define o PC como o primeiro byte para começar a executá-los.

Olá, setor de inicialização mundial

Agora que criamos um programa mínimo, vamos para o mundo olá.

A pergunta óbvia é: como fazer IO? Algumas opções:

  • peça ao firmware, por exemplo, BIOS ou UEFI, que faça por nós

  • VGA: região de memória especial que é impressa na tela se gravada. Pode ser usado no modo protegido.

  • escreva um driver e fale diretamente com o hardware da tela. Esta é a maneira "correta" de fazê-lo: mais poderoso, mas mais complexo.

  • porta serial . Este é um protocolo padronizado muito simples que envia e recebe caracteres de um terminal host.

    Nos desktops, fica assim:

    insira a descrição da imagem aqui

    Fonte .

    Infelizmente, ele não está exposto na maioria dos laptops modernos, mas é o caminho mais comum para as placas de desenvolvimento, veja os exemplos de ARM abaixo.

    É realmente uma pena, pois essas interfaces são realmente úteis para depurar o kernel do Linux, por exemplo .

  • use recursos de depuração de chips. O ARM chama de semi - hospedagem deles, por exemplo. Em hardware real, requer algum suporte extra de hardware e software, mas em emuladores pode ser uma opção conveniente e gratuita. Exemplo .

Aqui vamos fazer um exemplo de BIOS, pois é mais simples no x86. Mas observe que este não é o método mais robusto.

main.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 upstream .

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)
    }
}

Monte e vincule com:

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

Resultado:

insira a descrição da imagem aqui

E no T430:

insira a descrição da imagem aqui

Testado em: Lenovo Thinkpad T430, UEFI BIOS 1.16. Disco gerado em um host Ubuntu 18.04.

Além das instruções de montagem padrão da userland, temos:

  • .code16: diz ao GAS para gerar código de 16 bits

  • cli: desativar interrupções de software. Isso pode fazer com que o processador volte a funcionar após ohlt

  • int $0x10: faz uma chamada do BIOS. É isso que imprime os caracteres um por um.

Os sinalizadores de link importantes são:

  • --oformat binary: imprima o código de montagem binário bruto, não o envolva em um arquivo ELF, como é o caso dos executáveis ​​regulares da terra do usuário.

Para entender melhor a parte do script do vinculador, familiarize-se com a etapa de realocação do link: O que os vinculadores fazem?

Programas cooler x86 bare metal

Aqui estão algumas configurações bare metal mais complexas que eu já consegui:

Use C em vez de montagem

Resumo: use a inicialização múltipla do GRUB, que resolverá muitos problemas irritantes em que você nunca pensou. Veja a seção abaixo.

A principal dificuldade do x86 é que o BIOS carrega apenas 512 bytes do disco na memória e é provável que você exploda esses 512 bytes ao usar o C!

Para resolver isso, podemos usar um carregador de inicialização de dois estágios . Isso faz outras chamadas do BIOS, que carregam mais bytes do disco na memória. Aqui está um exemplo mínimo de montagem do estágio 2 do zero usando as chamadas int 0x13 do BIOS :

Alternativamente:

  • se você precisar apenas trabalhar no QEMU, mas não em hardware real, use a -kernelopção que carrega um arquivo ELF inteiro na memória. Aqui está um exemplo do ARM que eu criei com esse método .
  • para o Raspberry Pi, o firmware padrão cuida da imagem carregada para nós a partir de um arquivo ELF chamado kernel7.img, assim como o QEMU -kernel.

Apenas para fins educacionais, aqui está um exemplo C mínimo de um estágio :

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");
    };
}

entry.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 = .;
}

corre

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

Biblioteca padrão C

As coisas ficam mais divertidas se você também quiser usar a biblioteca padrão C, já que não temos o kernel Linux, o que implementa grande parte da funcionalidade da biblioteca padrão C através do POSIX .

Algumas possibilidades, sem acessar um sistema operacional completo como o Linux, incluem:

  • Escreva o seu próprio. É apenas um monte de cabeçalhos e arquivos C no final, certo? Certo??

  • Newlib

    Exemplo detalhado em: /electronics/223929/c-standard-libraries-on-bare-metal/223931

    Implementos newlib todas as coisas chatas não-OS específicos para você, por exemplo memcmp, memcpy, etc.

    Em seguida, fornece alguns stubs para você implementar os syscalls necessários.

    Por exemplo, podemos implementar exit()no ARM através de semi-hospedagem com:

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

    como mostrado neste exemplo .

    Por exemplo, você pode redirecionar printfpara os sistemas UART ou ARM ou implementar exit()com semi - hospedagem .

  • sistemas operacionais incorporados como FreeRTOS e Zephyr .

    Esses sistemas operacionais normalmente permitem desativar o agendamento preventivo, fornecendo controle total sobre o tempo de execução do programa.

    Eles podem ser vistos como uma espécie de Newlib pré-implementado.

Inicialização múltipla GNU GRUB

Os setores de inicialização são simples, mas não são muito convenientes:

  • você pode ter apenas um sistema operacional por disco
  • o código de carregamento deve ser muito pequeno e caber em 512 bytes
  • você tem que iniciar bastante, como mudar para o modo protegido

É por esses motivos que o GNU GRUB criou um formato de arquivo mais conveniente chamado de inicialização múltipla.

Exemplo de trabalho mínimo: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world

Também o uso no meu repositório de exemplos do GitHub para poder executar facilmente todos os exemplos em hardware real sem queimar o USB um milhão de vezes.

Resultado do QEMU:

insira a descrição da imagem aqui

T430:

insira a descrição da imagem aqui

Se você preparar seu sistema operacional como um arquivo de inicialização múltipla, o GRUB poderá encontrá-lo dentro de um sistema de arquivos comum.

É isso que a maioria das distribuições faz, colocando as imagens do SO em baixo /boot.

Os arquivos de inicialização múltipla são basicamente um arquivo ELF com um cabeçalho especial. Eles são especificados pelo GRUB em: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html

Você pode transformar um arquivo de inicialização múltipla em um disco inicializável com grub-mkrescue.

Firmware

Na verdade, seu setor de inicialização não é o primeiro software executado na CPU do sistema.

O que realmente roda primeiro é o chamado firmware , que é um software:

  • feita pelos fabricantes de hardware
  • fonte tipicamente fechada, mas provavelmente baseada em C
  • armazenado na memória somente leitura e, portanto, mais difícil / impossível de modificar sem o consentimento do fornecedor.

Firmwares conhecidos incluem:

  • BIOS : firmware x86 antigo completo. SeaBIOS é a implementação de código aberto padrão usada pelo QEMU.
  • UEFI : sucessor do BIOS, melhor padronizado, mas mais capaz e incrivelmente inchado.
  • Coreboot : a nobre tentativa de código aberto de arco cruzado

O firmware faz coisas como:

  • faça um loop sobre cada disco rígido, USB, rede etc. até encontrar algo inicializável.

    Quando rodamos o QEMU, -hdadiz que main.imgé um disco rígido conectado ao hardware, e hdaé o primeiro a ser testado, e é usado.

  • carregue os primeiros 512 bytes no endereço de memória RAM 0x7c00, coloque o RIP da CPU lá e deixe-o executar

  • mostrar coisas como o menu de inicialização ou as chamadas de impressão do BIOS no visor

O firmware oferece funcionalidade semelhante ao sistema operacional da qual a maioria dos sistemas operacionais depende. Por exemplo, um subconjunto Python foi portado para execução no BIOS / UEFI: https://www.youtube.com/watch?v=bYQ_lq5dcvM

Pode-se argumentar que os firmwares são indistinguíveis dos sistemas operacionais, e que o firmware é a única programação bare metal "verdadeira" que se pode fazer.

Como este desenvolvedor do CoreOS coloca :

A parte difícil

Quando você liga um PC, os chips que compõem o chipset (northbridge, southbridge e SuperIO) ainda não foram inicializados corretamente. Embora a ROM do BIOS esteja o mais longe possível da CPU, ela pode ser acessada pela CPU, porque precisa ser, caso contrário, a CPU não teria instruções para executar. Isso não significa que a ROM do BIOS esteja completamente mapeada, geralmente não. Mas apenas o suficiente é mapeado para iniciar o processo de inicialização. Quaisquer outros dispositivos, apenas esqueça.

Ao executar o Coreboot no QEMU, você pode experimentar as camadas mais altas do Coreboot e as cargas úteis, mas o QEMU oferece poucas oportunidades para experimentar o código de inicialização de baixo nível. Por um lado, a RAM funciona desde o início.

Estado inicial do BIOS pós

Como muitas coisas no hardware, a padronização é fraca, e uma das coisas em que você não deve confiar é o estado inicial dos registros quando o código começa a ser executado após o BIOS.

Então faça um favor a si mesmo e use algum código de inicialização como o seguinte: https://stackoverflow.com/a/32509555/895245

Os registros gostam %dse %estêm efeitos colaterais importantes, portanto, você deve zerá-los, mesmo que não os esteja usando explicitamente.

Observe que alguns emuladores são mais agradáveis ​​que o hardware real e fornecem um bom estado inicial. Então, quando você roda em hardware real, tudo quebra.

El Torito

Formato que pode ser gravado em CDs: https://en.wikipedia.org/wiki/El_Torito_%28CD-ROM_standard%29

Também é possível produzir uma imagem híbrida que funcione em ISO ou USB. Isso pode ser feito com grub-mkrescue( exemplo ) e também é feito pelo kernel do Linux no make isoimageuso isohybrid.

BRAÇO

No ARM, as idéias gerais são as mesmas.

Não há firmware pré-instalado semi-padronizado amplamente disponível como o BIOS para usar no IO; portanto, os dois tipos mais simples de IO que podemos fazer são:

  • serial, amplamente disponível em devboards
  • pisque o LED

Eu enviei:

Algumas diferenças do x86 incluem:

  • IO é feito escrevendo diretamente para endereços de mágica, não há ine outinstruções.

    Isso é chamado de E / S mapeada na memória .

  • para hardware real, como o Raspberry Pi, você pode adicionar o firmware (BIOS) à imagem do disco.

    Isso é bom, pois torna a atualização desse firmware mais transparente.

Recursos

Ciro Santilli adicionou uma nova foto
fonte
3
Os unikernels são uma alternativa para pessoas que não podem / não querem ter um nível tão baixo e ainda querem se beneficiar de sua presença muito baixa.
11116 AndreLDM
1
@AndreLDM Eu estava prestes a adicionar as notícias do Unikernel baseadas em Linux, mas ainda me senti muito nervoso: next.redhat.com/2018/11/14/ukl-a-unikernel-based-on-linux
Ciro Santilli 郝海东 冠状 病六四事件法轮功
14
Resposta realmente detalhada, mas "um programa que roda sem um sistema operacional é um sistema operacional" não é verdadeiro. Você pode escrever um programa que apenas acenda / apague um LED, mas que não o torne um SO. Alguns códigos de firmware que executam o microcontrolador na sua unidade flash não o tornam um SO. Um sistema operacional é no mínimo uma camada de abstração para escrever outro software com mais facilidade. Atualmente, no mínimo, eu diria que, se não houver um agendador, provavelmente não é um sistema operacional.
Vitali 26/11
4
Boa resposta, exceto pelo absurdo absoluto de que qualquer programa que não é executado em um sistema operacional é um sistema operacional.
curiousdannii
3
@ MichaelPetch hey, apenas para salvar o nulo no setor de inicialização :-) Provavelmente não vale a pena.
Ciro Santilli adicionou uma nova foto
3

Sistema operacional como inspiração

O sistema operacional também é um programa , portanto, também podemos criar nosso próprio programa criando do zero ou alterando (limitando ou adicionando) recursos de um dos pequenos sistemas operacionais e, em seguida, executá-lo durante o processo de inicialização (usando uma imagem ISO ) .

Por exemplo, esta página pode ser usada como ponto de partida:

Como escrever um sistema operacional simples

Aqui, todo o sistema operacional se encaixa totalmente em um setor de inicialização de 512 bytes ( MBR )!

Esse SO simples ou similar pode ser usado para criar uma estrutura simples que nos permita:

faça o carregador de inicialização carregar setores subsequentes no disco na RAM e pule para esse ponto para continuar a execução . Ou você poderia ler sobre o FAT12, o sistema de arquivos usado em unidades de disquete, e implementá-lo .

Existem muitas possibilidades, no entanto. Por exemplo, para ver um sistema operacional de linguagem assembly x86 maior , podemos explorar o sistema operacional MykeOS , x86, que é uma ferramenta de aprendizado para mostrar que os sistemas operacionais simples de modo real de 16 bits funcionam com: código bem comentado e extensa documentação .

Boot Loader como inspiração

Outro tipo comum de programas que são executados sem o sistema operacional também são os Carregadores de Inicialização . Podemos criar um programa inspirado nesse conceito, por exemplo, usando este site:

Como desenvolver seu próprio Boot Loader

O artigo acima apresenta também a arquitetura básica de tais programas :

  1. Carregamento correto na memória pelo endereço 0000: 7C00.
  2. Chamando a função BootMain que é desenvolvida no idioma de alto nível.
  3. Mostre a mensagem “” Olá, mundo… ”, de baixo nível” no visor.

Como podemos ver, essa arquitetura é muito flexível e nos permite implementar qualquer programa , não necessariamente um gerenciador de inicialização.

Em particular, mostra como usar a técnica "código misto", graças à qual é possível combinar construções de alto nível (de C ou C ++ ) com comandos de baixo nível (do Assembler ). Este é um método muito útil, mas precisamos lembrar que:

Para criar o programa e obter o arquivo executável, você precisará do compilador e vinculador do Assembler para o modo de 16 bits . Para C / C ++, você precisará apenas do compilador que pode criar arquivos de objeto para o modo de 16 bits .

O artigo mostra também como ver o programa criado em ação e como executar seus testes e depuração.

Aplicações UEFI como inspiração

Os exemplos acima usaram o fato de carregar o MBR do setor no suporte de dados. No entanto, podemos nos aprofundar mais, trabalhando, por exemplo, com os aplicativos UEFI :

Além de carregar um sistema operacional, o UEFI pode executar aplicativos UEFI, que residem como arquivos na partição do sistema EFI. Eles podem ser executados no shell de comando UEFI, pelo gerenciador de inicialização do firmware ou por outros aplicativos UEFI. Os aplicativos UEFI podem ser desenvolvidos e instalados independentemente do fabricante do sistema.

Um tipo de aplicativo UEFI é um carregador de SO , como GRUB, rEFInd, Gummiboot e Windows Boot Manager; que carrega um arquivo do SO na memória e o executa. Além disso, um carregador de SO pode fornecer uma interface com o usuário para permitir a seleção de outro aplicativo UEFI. Utilitários como o shell UEFI também são aplicativos UEFI.

Se gostaríamos de começar a criar esses programas , podemos, por exemplo, começar com estes sites:

Programando para EFI: Criando um Programa "Olá, Mundo" / Programação UEFI - Primeiros Passos

Explorando problemas de segurança como inspiração

É sabido que existe todo um grupo de softwares mal-intencionados (que são programas) que estão sendo executados antes do início do sistema operacional .

Um grande grupo deles opera no setor de MBR ou em aplicativos UEFI, assim como as soluções acima, mas também existem aqueles que usam outro ponto de entrada, como o Volume Boot Record (VBR) ou o BIOS :

Existem pelo menos quatro vírus de ataque do BIOS conhecidos , dois dos quais eram para fins de demonstração.

ou talvez outro também.

Ataques antes da inicialização do sistema

Os bootkits evoluíram do desenvolvimento da Prova de Conceito para a distribuição em massa e agora se tornaram efetivamente software de código aberto .

Diferentes maneiras de inicializar

Eu também acho que, nesse contexto, também vale a pena mencionar que existem várias formas de inicializar o sistema operacional (ou o programa executável destinado a isso) . Existem muitos, mas gostaria de prestar atenção ao carregamento do código da rede usando a opção Network Boot ( PXE ), que nos permite executar o programa no computador, independentemente do sistema operacional e mesmo de qualquer mídia de armazenamento que seja. diretamente conectado ao computador:

O que é o Boot de Rede (PXE) e como você pode usá-lo?

simhumileco
fonte