                     LINUX/I386 ֡ȥץȥ
                     ----------------------------

                    H. Peter Anvin <hpa@zytor.com>
                        ǽ 2000-10-29


                    ܸ:JF ץ

                      :
                         ɧ <takahiko@hakubi.co.jp>
                      ϼ:
                          <morimoto@xantia.citroen.org>
                        ͸  <setzer@mx3.tiki.ne.jp>
                          <hng@ps.ksky.ne.jp>

                        ǽ 2002-01-08


i386 ץåȥեǤϡLinux ͥ¿ʣʥ֡Ȥδ
ѤƤޤϰˤϡͥ뼫Ȥưǽ᡼ˤ
Ȥ˾˲äʣ PC ΥǥȤŪ¦̤
äơڤӡץڥ졼ƥ󥰥ƥȤƤΥꥢ⡼ DOS 
¾ξǤˤ PC ȳδԤѲˤäƿʲƤޤ

ߤǤϡͤĤΥС Linux/i386 ֡ȥץȥ뤬¸ߤޤ

Ťͥ:    zImage/Image ΥݡȤΤߡΥͥˤ
                 ޥɥ饤󤹤饵ݡȤƤʤΤ⤢ޤ

ץȥ 2.00: (ͥ 1.3.73) ֡ȥȥ֤ͥϢȤȤ
                 η줿ˡ˲äơbzImage  initrd 
                 ݡȤɲäޤΥåȥåΰ褬
                 ߲ǽǤ뤳ȤȤƲꤷƤϤޤ
                 setup.S Ϻֲǽˤʤޤ

ץȥ 2.01: (ͥ 1.3.76) ҡץСٹɲäޤ

ץȥ 2.02: (ͥ 2.4.0-test3-pre3) ޥɥ饤ץȥ롣
                 Υ¤򲼤ޤΥåȥåΰ
                 ʤȤˤꡢSMM ⤷ 32 ӥå BIOS ȥ
                 ݥȤ EBDA Ѥ륷ƥǤ⡢֡Ȥ
                 ʤޤzImage Ͽ侩ޤ󤬡ݡȤޤ

**** 쥤

Image ⤷ zImage ͥѤ륫ͥν
ޥåפϡŵŪˤϼΤ褦ˤʤäƤޤ

        |                                  |
0A0000  +----------------------------------+
        |  BIOS ѤͽѤ               |  ԲġBIOS EBDA ѤͽѤ
09A000  +----------------------------------+
        | å/ҡ/ޥɥ饤   |  ͥΥꥢ⡼ɥɤ
098000  +----------------------------------+
        | ͥ륻åȥå             |  ͥΥꥢ⡼ɥ
090200  +----------------------------------+
        | ͥ֡ȥ             |  ͥΥ쥬֡ȥ
090000  +----------------------------------+
        | ץƥȥ⡼ɥͥ         |  ͥ륤᡼ʬ
010000  +----------------------------------+
        | ֡ȥ                     |  <- ֡ȥȥݥ 0000:7C00
001000  +----------------------------------+
        | MBR/BIOS ѤͽѤ            |
000800  +----------------------------------+
        | ŵŪˤ MBR             |
000600  +----------------------------------+
        | BIOS ѤΤ                    |
000000  +----------------------------------+


bzImage ѤȤץƥȥ⡼ɥͥ 0x100000 ("
") ˺֤졢ͥΥꥢ⡼ɥ֥å (֡ȥ
åȥåסå/ҡ)ϡ0x10000 ̥νλ֤
֤ʤФɤˤǤֲǽȤƤޤԱˤ⡢ץȥ
2.00 ȥץȥ 2.01 ϡ0x9XXXX ΥϰϤ˥ޥɥ饤
¸ߤ뤳Ȥ׵ᤷΥϰϤϽưͥˤäưȤ
񤭤ޤץȥ 2.02 Ǥϡޤ

"" ֡ȥ̥κǹ̥ݥȡ 
ǽʸ¤㤯ݤĤȤ˾ޤȤǤʤʤ顢 BIOS ˤϡ
̥ξ¶᤯ˡĥ BIOS ǡΰȸƤФ뤫ʤ礭̤
֤Τ⤢뤫Ǥ֡ȥϡ"INT 12h" BIOS
Ȥäơ̥꤬ɤ줯餤ѤǤ뤫ǧʤ
ʤޤ

Աˤ INT 12h ­򸡽Фˤϡ֡ȥ
桼˥顼åФ餤ΤȤǤޤ󡣤Τᡢ
֡ȥϡŪ˲ǽʸ¤ꡢǤʤΰ褦
߷פ٤Ǥ0x90000 Ȥ˥ǡ񤭹ޤ뤳Ȥ
ɬפȤ zImage ͥŤ bzImage ͥΤˤϡ֡
 0x9A000 ΥȤʤ褦ˤʤФʤޤ
¿ BIOS ΰ˲ƤޤΤǤ

**** ꥢ⡼ɥͥإå

ʸ⡢ڤӡͥ֡ȥΤɤΰ֤ˤƤ⡢
""  512 ХȤΤȤǤǥμºݤΥȤ
طޤ

Linux ͥɤǽΥƥåפǤϡꥢ⡼ɥ
(֡ȥȥåȥåץ) ɤեå 0x01f1 
¸ߤ벼Υإå򸡺ʤФʤޤ󡣥֡ȥϺǽ
ĤΥ (1K) ɤ줫֡ȥåץ
Ĵ٤뤳ȤǤޤꥢ⡼ɥɤϹפ 32K ޤǲǽǤ

إåϼΤ褦ˤʤäƤޤ

եå ץȥ ̾            ̣
/

01F1/1     ALL        setup_sects     ñ̤ΥåȥåפΥ
01F2/2     ALL        root_flags      åȤƤС꡼ɥ꡼ root ޥȤ
01F4/2     ALL        syssize         Բġbootsect.S ˤѤΤߡ
01F6/2     ALL        swap_dev        Բġ켰
01F8/2     ALL        ram_size        Բġbootsect.S ˤѤΤߡ
01FA/2     ALL        vid_mode        ӥǥ⡼
01FC/2     ALL        root_dev        ǥեȤΥ롼ȥǥХֹ
01FE/2     ALL        boot_flag       ޥåʥС 0xAA55
0200/2     2.00+      jump            ̿
0202/4     2.00+      header          ޥåʥС "HdrS"
0206/2     2.00+      version         ݡȤ֡ȥץȥΥС
0208/4     2.00+      realmode_swtch  ֡ȥեå ()
020C/4     2.00+      start_sys       ͥСʸؤ
0210/1     2.00+      type_of_loader  ֡ȥ̻
0211/1     2.00+      loadflags       ֡ȥץȥ륪ץե饰
0212/2     2.00+      setup_move_size ̥ꥵذư (եåȶ˻)
0214/4     2.00+      code32_start    ֡ȥեå ()
0218/4     2.00+      ramdisk_image   initrd ɥɥ쥹 (֡ȥˤꥻåȤ)
021C/4     2.00+      ramdisk_size    initrd  (֡ȥˤꥻåȤ)
0220/4     2.00+      bootsect_kludge Բġbootsect.S ˤѤΤߡ
0224/2     2.01+      heap_end_ptr    åȥå׽λְʹߤΥե꡼
0226/2     N/A        pad1            ̤
0228/4     2.02+      cmd_line_ptr    ͥ륳ޥɥ饤ؤ 32 ӥåȥݥ

ߴΤᡢsetup_sects եɤ 0 ξˤϡºݤͤ
4 Ȥʤޤ

եå 0x202 ΰ֤˥ޥåʥС "HdrS" (0x53726448) ȯǤʤ
硢֡ȥץȥΥС "Ť" ǤŤͥɤ
ȤˤϡΥѥ᡼ꤵޤ

        ᡼ = zImage
        initrd ̤ݡ
        ꥢ⡼ɥͥ 0x90000 ֤ʤФʤʤ

ʳʤС"version" եɤϥץȥΥСޤ
ޤ㤨СץȥС 2.01 ϡ0x0201 򤳤Υեɤ
ޤǤޤإåΥեɤ򥻥åȤȤˤϡΥץ
ȥСǥݡȤƤեɤΤߤ򥻥åȤ褦
ʤФʤޤ

ۤȤɤΥ֡ȥϡñˤΥåȥɥ쥹˥ͥľ
ɤǤ礦Τ褦ʥ֡ȥϡإåΤۤȤɤ
եɤˤĤƤϡ뤳ȤˤĤƿۤɬפϤޤ
ȤϤΤΡΥեɤʤФʤޤ


  vid_mode:
        ̤ʥޥɥ饤󥪥ץפ򻲾ȤƤ

  type_of_loader:
        ʤΥ֡ȥ arch/i386/boot/setup.S ǳƤ
        Ƥ뼱̻ҤäƤʤСͤޤǤʤ
        Сˤ 0xFF ޤ

  loadflags, heap_end_ptr:
        ץȥС 2.01 ʾʤСåȥåץҡפ
        եåȥߥåȤ head_end_ptr 졢loadflags  0x80
        ӥå (CAN_USE_HEAP) 򥻥åȤޤheap_end_ptr ϡå
        åפγϰ (եå 0x0200) а֤Ǥ

  setup_move_size:
        ץȥ 2.00 ⤷ 2.01 ȤäƤȤꥢ⡼
        ͥ뤬 0x90000 ˥ɤʤʤСꥢ⡼ɥͥ
        ǥ󥰥ǡΤۤɤ˰ưޤ
        ꥢ⡼ɥͥ뼫Τ¾ɲäΥǡ (ͥ륳ޥ
        饤ʤ) ưˤϡΥեɤޤ

  ramdisk_image, ramdisk_size:
        ֡ȥ˥ RAM ǥ (initrd) ɤƤ硢
        RAM ǥǡؤ 32 ӥåȥݥ󥿤 ramdisk_image ˥åȤ
         RAM ǥǡΥ ramdisk_size ˥åȤޤ

        initrd ŵŪˤϡΤǤ¤̤֤٤Ǥ
        ʤʤ顢ʤСưͥν󥹤ˤä
        񤭤Ƥޤ⤷ʤǤʤ顢
        ͥ initrd 򻲾ȤΤʤСinitrd 򥢥ɥ쥹
        0x3C000000 ֤ƤϤޤ

  cmd_line_ptr:
        ץȥС 2.02 ʾʤСϡͥ륳ޥ
        ɥ饤ؤ 32 ӥåȥݥ󥿤Ǥͥ륳ޥɥ饤ϡ
        åȥå׽λ֤ 0xA0000 δ֤ʤСɤˤǤ֤
        뤳ȤǤޤȤޥɥ饤򥵥ݡȤƤʤ
        Ǥ⡢ΥեɤʤФʤޤ󡣤Τ褦ʾ
        ϡʸؤ褦ˤޤ (⤷ϡɤΤʸ
        "auto" ؤ褦ˤ뤳ȤǤ) ΥեɤΤޤ
        Ǥȡͥϡ֡ȥץȥ 2.02 򥵥ݡȤ
        ƤʤȲꤷƤޤޤ

**** ͥ륳ޥɥ饤

ͥ륳ޥɥ饤ϡ֡ȥͥϢȤ뤿
פˡȤʤäƤƤޤĤΥץϡ֡ȥ
ȤˤطƤޤ "̤ʥޥɥ饤󥪥ץ" 
ȤƤ

ͥ륳ޥɥ饤ϡ̥뽪ü줿Ĺ 255 ޤǤʸ
ץ饹ǸΥ̥Ǥ

֡ȥץȥС 2.02 ʹߤʤСͥ륳ޥ
饤Υɥ쥹ϡإåե cmd_line_ptr Ϳޤ
() 

ץȥС 2.02 ʤСͥ륳ޥɥ饤
ΥץȥѤϤޤ

        եå 0x0020 ()  "cmd_line_magic" ˡޥå
        ʥС 0xA33F ޤ

        եå 0x0022 ()  "cmd_line_offset" ˡͥ
        ޥɥ饤ΥեåȤޤ (ꥢ⡼ɥͥ
        ϰ֤Ф) 

        ͥ륳ޥɥ饤 setup_move_size ǥС
        ϰϤˤʤФʤʤΤǡΥեɤĴ
        ɬפޤ


**** ֡

ȤơΥꥢ⡼ɥȥ쥤Ȥꤷޤ

        0x0000-0x7FFF   ꥢ⡼ɥͥ
        0x8000-0x8FFF   åȥҡ
        0x9000-0x90FF   ͥ륳ޥɥ饤

Υ֡ȥϡإå˲ΥեɤʤФʤޤ

        unsigned long base_ptr; /* ꥢ⡼ɥȤΥ١ɥ쥹 */

        if ( setup_sects == 0 ) {
                setup_sects = 4;
        }

        if ( protocol >= 0x0200 ) {
                type_of_loader = <type code>;
                if ( loading_initrd ) {
                        ramdisk_image = <initrd_address>;
                        ramdisk_size = <initrd_size>;
                }
                if ( protocol >= 0x0201 ) {
                        heap_end_ptr = 0x9000 - 0x200;
                        loadflags |= 0x80; /* CAN_USE_HEAP */
                }
                if ( protocol >= 0x0202 ) {
                        cmd_line_ptr = base_ptr + 0x9000;
                } else {
                        cmd_line_magic  = 0xA33F;
                        cmd_line_offset = 0x9000;
                        setup_move_size = 0x9100;
                }
        } else {
                /* ȤƤŤͥ */

                cmd_line_magic  = 0xA33F;
                cmd_line_offset = 0x9000;

                /* ȤƤŤͥϡΥꥢ⡼ɥɤ
                   0x90000 ˥ɤʤФʤʤ */

                if ( base_ptr != 0x90000 ) {
                        /* ꥢ⡼ɥͥ򥳥ԡ */
                        memcpy(0x90000, base_ptr, (setup_sects+1)*512);
                        /* ޥɥ饤򥳥ԡ */
                        memcpy(0x99000, base_ptr+0x9000, 256);

                        base_ptr = 0x90000;                 /* ֤줿 */
                }

                /* 32K ޤǥ򥯥ꥢ뤳Ȥ侩 */
                memset(0x90000 + (setup_sects+1)*512, 0,
                       (64-(setup_sects+1))*512);
        }


**** ͥλĤʬɤ

ꥢ⡼ɥͥϡͥեΥեå (setup_sects+1)*512
Ϥޤޤ (ٽҤ٤ޤsetup_sects  0 ΤȤϡºݤͤ
4 Ǥ) ꥢ⡼ɥͥϡImage/zImage ͥʤС
ɥ쥹 0x10000 ˡbzImage ͥʤ 0x100000 ˥ɤ
ʤФʤޤ

ץȥ뤬 2.00 ʾǡloadflags եɤ 0x01 ӥå
(LOAD_HIGH) åȤƤʤСͥ bzImage Ǥ

        is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);
        load_address = is_bzImage ? 0x100000 : 0x10000;

Image/zImage ͥϡ512K ΥޤǲǽʤΤǡ0x10000 
0x90000 ϰϤȤȤȤդƤϡ
Υͥ뤬ꥢ⡼ʬ 0x90000 ˥ɤȤ
ȤʤѤ׵ǤȤȤ̣ޤbzImage 
ͥϡä¿ν󶡤ޤ


**** ̤ʥޥɥ饤󥪥ץ

֡ȥˤä󶡤륳ޥɥ饤󤬥桼ˤäϤ
ʤС桼ϲ˼ޥɥ饤󥪥ץư뤳Ȥ
Ƥ⤫ޤޤ󡣤̾ƤͥˤȤäƼ¼Ū
̣櫓ǤϤʤˤƤ⡢ͥ륳ޥɥ饤󤫤
٤ǤϤޤ󡣥֡ȥѤΥޥɥ饤󥪥ץɲä
ɬפȤ֡ȥκԤϡΥץ󤬡ߤ⤷Ͼ
ͥ륪ץȶ礷ʤ褦ˤ뤿ᡢ
linux/Documentation/kernel-parameters.txt ˡΥץ
Ͽ٤Ǥ

  vga=<mode>
        ˤ <mode> ϡ (C εˡǡ10 ʿ8 ʿ
        16 ʿΤ줫) ⤷ϡ"normal" (0xFFFF ̣)
        "ext" (0xFFFE  ̣)"ask" (0xFFFD ̣) Ȥ
        ʸΤ줫Ǥͤϡޥɥ饤󤬲Ϥ
        ͥ뤬ѤȤˡvid_mode եɤ˥å
        ʤФʤޤ


  mem=<size>
        <size>  C εˡˤǡK, M, G (<<10, <<20, <<30 
        ̣ޤ) ˤĤ뤳ȤǤޤˤꡢ
        ͥ˥νλ֤ޤϡinitrd ֲǽ
        ֤˱ƶͿޤȤΤϡinitrd ϥνλ
        ᤯֤뤫ǤΥץϡͥȥ֡
         ** Ф륪ץǤ뤳ȤդƤ!

  initrd=<file>
        initrd ɤޤ<file> ΰ̣ϡ餫˥֡ȥ
        ¸Ǥꡢ֡ȥ (LILO ʤ) ˤϡΤ褦
        ޥɤäƤʤΤ⤢ޤ


ˡ桼Υޥɥ饤˲ΥץäƤ
֡ȥ⤢ޤ

  BOOT_IMAGE=<file>
        ɤ֡ȥ᡼ٽҤ٤ޤ<file> ΰ̣ϡ
        餫˥֡ȥ˰¸Ƥޤ

  auto
        Ūʥ桼ˤʤǥ֡Ȥ륫ͥ롣

Υץ󤬥֡ȥˤɲäʤС桼
⤷ϥե졼Υޥɥ饤ˡ
 *ǽ* ֤뤳Ȥ侩ޤǤʤ硢
"init=/bin/sh"  "auto" ץǺ𤷤ƤޤǤ礦


**** ͥ餻

ͥ륨ȥݥȤ˥פ뤳Ȥˤꡢͥϥ
ޤͥ륨ȥݥȤϡꥢ⡼ɥͥγϰ
 ** եå 0x20 ΤȤ֤ޤϡ
⤷ꥢ⡼ɥͥ륳ɤ 0x90000 ˥ɤ硢ͥ
ȥݥȤ 9020:0000 ˤʤ뤳Ȥ̣Ƥޤ

ȥǤϡds = es = ss ϥꥢ⡼ɥͥ륳ɤγϰ
(⤷⥳ɤ 0x90000 ˥ɤƤʤ 0x9000) ؤ
sp Ŭڤ˥åȤ ̾ϥҡפΥȥåפؤߤ
ػߤ٤ǤˡͥΥХݸ뤿ᡢ֡
 fs = gs = ds = es = ss ȥåȤ뤳Ȥ侩ޤ


嵭ǤϡΤ褦ˤ뤳ȤˤʤǤ礦

        /* : "Ť" ͥץȥξ硢base_ptr ϡλ
           0x90000 ǤʤФʤʤΥץ륳ɤ򻲾ȤΤȡ*/

        seg = base_ptr >> 4;

        cli();  /* ߤػߤˤ! */

        /* ꥢ⡼ɥͥ륹å򥻥åȤ */
        _SS = seg;
        _SP = 0x9000;   /* SS ɸ塢 SP ɤ! */

        _DS = _ES = _FS = _GS = seg;
        jmp_far(seg+0x20, 0);   /* ͥ餻 */


֡ȥեåԡɥ饤֤˥ʤСͥ
餻˥եåԡ⡼ڤ뤳Ȥ侩ޤȤΤϡ
ͥΥ֡ȤϳߤػߤΤޤޤˤƤΤǡ⡼
դˤʤʤǤäˡɤ줿ͥ뤬եåԡ
ɥ饤Ф׵ɥ⥸塼ȤƻäƤ!


**** ٤ʥ֡Ȼեå

⤷֡ȥäŨŪʴĶ (DOS  LOADLIN ʤ) 
ϡɸŪ׵˽ȤԲǽǤ礦Τ褦
֡ȥϡ⤷åȤƤʤСŬڤʳǥͥ
äƼ¹Ԥ벼˼եåȤäƤ⤫ޤޤ󡣤
եåλѤϡ餯ŪǽʤȤƤΤ߹θ٤Ǥ!

: ƤΥեåϡޤʤȤ %esp, %ebp, %esi, %edi ¸
Ȥ׵ᤵޤ

  realmode_swtch:
        ץƥȥ⡼ɤ˰ܹԤľ˼¹Ԥ 16 ӥåȥꥢ⡼ɤ
        far ֥롼󡣥ǥեȤΥ롼ϡNMI ̵ˤΤǡ
        ʤΥ롼⤪餯٤Ǥ礦

  code32_start:
        ץƥȥ⡼ɰܹľ塢ͥ *פ*
        32 ӥåȤΥեåȥ⡼ɤΥ롼CS ʳΥȤ
        åȤƤޤ¾ΥȤϡʤȤ
        KERNEL_DS (0x18) ˥åȤʤФʤޤ

        եåλ塢ʤΥ֡ȥ񤭤ˤ
        եɤ˥åȤƤɥ쥹إפʤ
        ʤޤ

