オペレーティングシステムなしでプログラムを実行する方法


239

オペレーティングシステムを実行せずに、プログラムを単独でどのように実行しますか?コンピュータを起動時にロードして実行できるアセンブリプログラムを作成できますか?たとえば、フラッシュドライブからコンピュータを起動し、CPU上のプログラムを実行しますか?


4
どのアーキテクチャで?x86?腕?
キッシエル2014

1
私は一般的に言っていましたが、おそらくx86またはx64
user2320609 2014

2
はい、それはまさにプロセッサの起動方法です。Cはアセンブリである必要はありません。Cは、ブートストラップやその他のサポートのために、少しのasmとともに使用されることがよくあります。
old_timer 14

23
考えてみてください。そのような機能がない場合、OS自体はどのように起動して実行されますか?:)
Seva Alekseyev

回答:


153

オペレーティングシステムを実行せずに、プログラムを単独でどのように実行しますか?

バイナリコードを、再起動後にプロセッサが検索する場所(たとえば、ARMのアドレス0)に配置します。

コンピュータが起動時にロードして実行できるアセンブリプログラムを作成できますか(たとえば、フラッシュドライブからコンピュータを起動し、ドライブ上にあるプログラムを実行します)?

質問に対する一般的な回答:実行できます。これはしばしば「ベアメタルプログラミング」と呼ばれます。フラッシュドライブから読み取るには、USBとは何かを知り、このUSBで動作するいくつかのドライバーが必要です。このドライブ上のプログラムは、特定のファイルシステム上で特定の形式にする必要もあります...これは通常、ブートローダーが行うことですが、プログラムに独自のブートローダーを含めて、ファームウェアのみが必要な場合は自己完結型にすることもできますコードの小さなブロックをロードします。

多くのARMボードでは、これらの機能のいくつかを実行できます。一部には、基本的なセットアップに役立つブートローダーがあります。

ここでは、Raspberry Piで基本的なオペレーティングシステムを実行する方法に関する優れたチュートリアルを見つけることができます。

編集:この記事とwiki.osdev.org全体で、ほとんどの質問に答え ますhttp://wiki.osdev.org/Introduction

また、ハードウェアで直接実験したくない場合は、qemuなどのハイパーバイザーを使用して仮想マシンとして実行できます。仮想化されたARMハードウェア「hello world」を直接実行する方法については、こちらをご覧ください


722

実行可能な例

OSなしで実行できるいくつかの非常に小さなベアメタルのHello Worldプログラムを作成して実行してみましょう。

より安全で開発に便利なため、QEMUエミュレーターでも可能な限り試します。QEMUテストは、QEMU 2.11.1がプリパッケージされたUbuntu 18.04ホストで行われました。

以下のすべてのx86例のコードは、このGitHubリポジトリにあります。

x86の実際のハードウェアで例を実行する方法

実際のハードウェアでサンプルを実行すると危険な場合があることを覚えておいてください。たとえば、誤ってディスクを消去したり、ハードウェアを壊したりする可能性があります。これは、重要なデータを含まない古いマシンでのみ実行してください。または、Raspberry Piなどの安価なセミディスポーザブルdevboardを使用することもできます。以下のARMの例を参照してください。

典型的なx86ラップトップの場合、次のようなことを行う必要があります。

  1. 画像をUSBスティックに書き込みます(データが破壊されます!):

    sudo dd if=main.img of=/dev/sdX
    
  2. USBをコンピュータに接続する

  3. それをオン

  4. USBから起動するように指示します。

    これは、ファームウェアがハードディスクの前にUSBを選択することを意味します。

    これがマシンのデフォルトの動作でない場合は、電源投入後、USBからの起動を選択できる起動メニューが表示されるまで、Enter、F12、ESCなどの奇妙なキーを押し続けます。

    多くの場合、これらのメニューで検索順序を構成できます。

たとえば、T430では次のように表示されます。

オンにした後、Enterキーを押してブートメニューに入る必要があります。

ここに画像の説明を入力してください

次に、F12を押してUSBを起動デバイスとして選択する必要があります。

ここに画像の説明を入力してください

そこから、次のようにUSBを起動デバイスとして選択できます。

ここに画像の説明を入力してください

または、起動順序を変更してUSBの優先順位を高くし、毎回手動で選択する必要がないようにするには、[スタートアップ割り込みメニュー]画面でF1を押して、次の場所に移動します。

ここに画像の説明を入力してください

ブートセクター

x86で実行できる最も単純で最低レベルのことは、ブートセクターの一種であるマスターブートセクター(MBR)を作成し、それをディスクにインストールすることです。

ここでは、1回の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進数で:hltCPUの動作を停止するように指示する命令のエンコーディング。

    したがって、プログラムは何も実行せず、開始と停止のみを行います。

    \x16進数はPOSIXで指定されていないため、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

    これらは、バイト511および512でなければならない2つの必須のマジックバイトです。

    BIOSは、起動可能なディスクを探してすべてのディスクを調べ、2つの魔法のバイトを持つ起動可能なディスクのみを考慮します。

    存在しない場合、ハードウェアはこれを起動可能なディスクとして扱いません。

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の例を実行します。ただし、これが最も堅牢な方法ではないことに注意してください。

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アップストリーム

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呼び出しを行います。これは、文字を1つずつ印刷するものです。

重要なリンクフラグは次のとおりです。

  • --oformat binary:通常のユーザーランド実行可能ファイルの場合のように、生のバイナリアセンブリコードを出力します。ELFファイル内にラップしないでください。

リンカスクリプト部分をよりよく理解するには、リンクの再配置手順に慣れておきます。リンカは何をしますか?

Cooler x86ベアメタルプログラム

以下に、私が達成したいくつかのより複雑なベアメタルセットアップを示します。

アセンブリの代わりにCを使用

概要:GRUBマルチブートを使用してください。これは、あなたが考えたことのない多くの迷惑な問題を解決します。以下のセクションを参照してください。

x86の主な問題は、BIOSがディスクからメモリに512バイトしかロードしないことです。Cを使用すると、これらの512バイトが爆発する可能性があります。

これを解決するには、2段階のブートローダーを使用します。これにより、BIOS呼び出しがさらに行われ、ディスクからメモリに読み込まれるバイト数が増えます。以下は、int 0x13 BIOS呼び出しを使用した、最初からの最小限のステージ2アセンブリの例です。

または:

  • QEMUでのみ機能し、実際のハードウェアでは機能しない場合は、-kernelオプションを使用して、ELFファイル全体をメモリにロードします。以下は、そのメソッドで作成したARMの例です。
  • Raspberry Piの場合、kernel7.imgQEMUと同様に、デフォルトのファームウェアが、という名前のELFファイルからのイメージのロードを処理-kernelします。

教育目的のみのために、これは1段階の最小限の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");
    };
}

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

リンカー.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標準ライブラリ

ただし、C標準ライブラリも使用したい場合は、POSIXを介してC標準ライブラリの機能の多くを実装するLinuxカーネルがないため、物事はさらに楽しくなります。

Linuxのような本格的なOSに行かなくても、いくつかの可能性があります。

  • 自分で書いてください。結局のところ、ヘッダーとCファイルの集まりですよね?正しい??

  • ニューリブ

    詳細な例:https : //electronics.stackexchange.com/questions/223929/c-standard-libraries-on-bare-metal/223931

    NEWLIB用具あなたのためのすべての退屈の非OSの特定のもの、例えばmemcmpmemcpyなど

    次に、必要なシステムコールを実装するためのスタブをいくつか提供します。

    たとえば、次のexit()セミホスティングを使用してARMに実装できます。

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

    この例に示すように。

    たとえばprintf、UARTまたはARMシステムにリダイレクトしたりexit()セミホスティングを実装したりできます。

  • FreeRTOSZephyrなどの組み込みオペレーティングシステム。

    このようなオペレーティングシステムでは、通常、プリエンプティブスケジューリングをオフにできるため、プログラムの実行時間を完全に制御できます。

    これらは、事前に実装された一種のNewlibと見なすことができます。

GNU GRUBマルチブート

ブートセクターは単純ですが、あまり便利ではありません。

  • ディスクごとに1つのOSしか使用できません
  • ロードコードは本当に小さく、512バイトに収まる必要があります
  • プロテクトモードに移行するなど、多くのスタートアップを自分で行う必要があります。

これらの理由により、GNU GRUBはマルチブートと呼ばれるより便利なファイル形式を作成しました。

最小限の動作例:https : //github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world

また、GitHubのサンプルリポジトリでも使用して、USBを100万回書き込むことなく、実際のハードウェアですべてのサンプルを簡単に実行できるようにしています。

QEMUの結果:

ここに画像の説明を入力してください

T430:

ここに画像の説明を入力してください

OSをマルチブートファイルとして準備すると、GRUBは通常のファイルシステム内でそれを見つけることができます。

これは、ほとんどのディストリビューションがOSイメージをに配置すること/bootです。

マルチブートファイルは基本的に、特別なヘッダーを持つELFファイルです。それらはhttps://www.gnu.org/software/grub/manual/multiboot/multiboot.htmlにある GRUBによって指定されています。

を使用して、マルチブートファイルを起動可能なディスクに変換できますgrub-mkrescue

ファームウェア

実際、ブートセクターは、システムのCPUで実行される最初のソフトウェアではありません。

最初に実際に実行されるのは、ソフトウェアであるいわゆるファームウェアです。

  • ハードウェアメーカーが作成
  • 通常はクローズドソースですが、おそらくCベースです
  • 読み取り専用メモリに保存されるため、ベンダーの同意なしに変更することは困難/不可能です。

よく知られているファームウェアは次のとおりです。

  • BIOS:すべて存在する古いx86ファームウェア。SeaBIOSはQEMUで使用されるデフォルトのオープンソース実装です。
  • UEFI:BIOSの後継であり、標準化は進んでいますが、より機能が高く、非常に肥大化しています。
  • Coreboot:高貴なクロスアーチオープンソースの試み

ファームウェアは次のようなことを行います:

  • 起動可能なものが見つかるまで、各ハードディスク、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と区別がつかず、そのファームウェアは、実行できる唯一の「真の」ベアメタルプログラミングであると主張できます。

このCoreOS開発者がそれを置くように

難しい部分

PCの電源を投入しても、チップセットを構成するチップ(ノースブリッジ、サウスブリッジ、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)で行うことができ、Linuxカーネルでmake isoimageを使用して行うこともできますisohybrid

ARMでは、一般的な考え方は同じです。

私たちがIOに使用するためのBIOSのような広く利用可能な半標準化されたプリインストールされたファームウェアはありません。

  • シリアル、開発ボードで広く利用可能
  • LEDを点滅させる

アップロードしました:

x86とのいくつかの違いは次のとおりです。

  • IOが直接魔法のアドレスに書き込むことによって行われますが、何もありませんinout指示。

    これは、メモリマップIOと呼ばれます

  • Raspberry Piなどの一部の実際のハードウェアでは、自分でファームウェア(BIOS)をディスクイメージに追加できます。

    それはファームウェアの更新をより透過的にするので、それは良いことです。

資源


3
ユニカーネルは、それほど低いレベルに行きたくない、または行きたくない、そして非常に低い設置面積から利益を得たいという人々にとっての選択肢です。
AndreLDM 2018年

1
@AndreLDM私はそのLinuxベースのユニカーネルニュースを追加する寸前でしたが、まだエッジが強すぎました: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

インスピレーションとしてのオペレーティングシステム

オペレーティングシステムは、プログラムである、我々はまたできるので、ゼロから作成または変更することによって、私たち自身のプログラムを作成するの1の特徴(制限または追加)小さなオペレーティングシステム、およびその後、ブートプロセスの間にそれを実行します(使用してISOイメージを) 。

たとえば、このページを出発点として使用できます。

単純なオペレーティングシステムの作成方法

ここでは、オペレーティングシステム全体が512バイトのブートセクター(MBR)に完全に適合しています。

そのようなまたは類似した単純なOSを使用して、以下を可能にする単純なフレームワーク作成できます

作るRAMにディスク上のブートローダーのロード以降のセクタを、そして実行を継続するために、そのポイントにジャンプ。または、フロッピードライブで使用されるファイルシステムであるFAT12を読み取り、それを実装することもできます。

ただし、多くの可能性があります。たとえば、より大きなx86アセンブリ言語OSを確認するには、よくコメントされたコード広範なドキュメントを備えたシンプルな16ビットリアルモードOSの動作を示す学習ツールであるx86オペレーティングシステムであるMykeOSを探索します

インスピレーションとしてのブートローダー

オペレーティングシステムなしで実行される他の一般的な種類のプログラムもブートローダーです。このようなコンセプトにインスパイアされたプログラムを、たとえばこのサイトを使用して作成できます。

独自のブートローダーを開発する方法

上記の記事は、そのようなプログラムの基本的なアーキテクチャも示しています

  1. 0000:7C00アドレスによるメモリへの正しい読み込み。
  2. 高水準言語で開発されたBootMain関数呼び出す
  3. 「” Hello、world…”を低レベルから」というメッセージをディスプレイに表示します。

ご覧のとおり、このアーキテクチャは非常に柔軟であり、必ずしもブートローダーではなく、任意のプログラムを実装できます。

具体的には、それを使用する方法を示し、「混合コード」手法が可能であるおかげで、高レベルの構造を組み合わせること(からC又はC ++、低レベルのコマンドで(からアセンブラ)。これは非常に便利な方法ですが、次のことを覚えておく必要があります。

プログラムをビルドして実行可能ファイル取得するには、16ビットモードのアセンブラーのコンパイラーとリンカーが必要ですC / C ++の場合、16ビットモードのオブジェクトファイルを作成できるコンパイラのみが必要です

この記事では、作成されたプログラムの動作を確認する方法と、テストとデバッグを実行する方法も示しています。

インスピレーションとしてのUEFIアプリケーション

上記の例では、セクターMBRをデータメディアにロードするという事実を使用しました。ただし、たとえばUEFIアプリケーションを使ってプレーティングすることで、さらに深く掘り下げることができます

OSをロードするだけでなく、UEFIはEFIシステムパーティション上のファイルとして存在するUEFIアプリケーションを実行できます。これらは、UEFIコマンドシェルから、ファームウェアのブートマネージャーによって、または他のUEFIアプリケーションによって実行できます。UEFIアプリケーションは、システムメーカーとは関係なく開発およびインストールできます。

UEFIアプリケーションの一種は、GRUB、rEFInd、Gummiboot、Windows Boot ManagerなどのOSローダーです。OSファイルをメモリにロードして実行します。また、OSローダーは、実行する別のUEFIアプリケーションを選択できるユーザーインターフェイスを提供できます。UEFIシェルなどのユーティリティもUEFIアプリケーションです。

そのようなプログラムの作成を開始したい場合は、たとえば、次のWebサイトから始めることができます。

EFIのプログラミング:「Hello、World」プログラムの作成 / UEFIプログラミング-最初のステップ

インスピレーションとしてのセキュリティ問題の調査

オペレーティングシステムが起動する前に実行されている悪意のあるソフトウェア(プログラム)のグループ全体があることはよく知られています

それらの巨大なグループは、上記のすべてのソリューションと同様に、MBRセクターまたはUEFIアプリケーションで動作しますが、ボリュームブートレコード(VBR)やBIOSなどの別のエントリポイントを使用するものもあります

少なくとも4つの既知のBIOS攻撃ウイルスがあり、そのうち2つはデモンストレーション用です。

またはおそらく別のものも。

システム起動前の攻撃

ブートキットは、概念実証の開発から大量配布に進化し、現在は事実上オープンソースソフトウェアになっています。

起動するさまざまな方法

また、このコンテキストでは、オペレーティングシステム(またはこのための実行可能プログラム)を起動するさまざまな形式あることにも言及する価値があると思います。そこに多くがありますが、私は注意を払うしたいネットワークからコードをロードするネットワークブートオプション(使用してPXE私たちは、コンピュータ上のプログラムを実行することができます)、かかわらず、そのオペレーティングシステムのもかかわらず、任意の記憶媒体のありますコンピュータに直接接続:

ネットワークブート(PXE)とは何ですか、またどのように使用できますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.