ããŒãããŒããŒããã«ãŒãã«ãžä»¥åã®
èšäºãèªãã ããäœã¬ãã«ããã°ã©ãã³ã°ã®ããã®ç§ã®æ°ããè¶£å³ã«ã€ããŠç¥ã£ãŠããŸãã
x86_64
Linuxåãã®
x86_64
ããã°ã©ãã³ã°ã«é¢ããèšäºãããã€ãæžãããšåæã«ãLinuxã«ãŒãã«ã®ãœãŒã¹ã³ãŒããæãäžããŸããã
ç§ã¯ãäœã¬ãã«ã®ãã®ãã©ã®ããã«æ©èœããããçè§£ããããšã«éåžžã«èå³ããããŸãïŒããã°ã©ã ãç§ã®ã³ã³ãã¥ãŒã¿ãŒã§å®è¡ãããæ¹æ³ãããããã¡ã¢ãªã«é
眮ãããæ¹æ³ãã«ãŒãã«ãããã»ã¹ãšã¡ã¢ãªã管çããæ¹æ³ããããã¯ãŒã¯ã¹ã¿ãã¯ãäœã¬ãã«ã§åäœããæ¹æ³ãªã©ã ããã§ã
x86_64ã¢ãŒããã¯ãã£çšã®Linuxã«ãŒãã«ã«é¢ããå¥ã®ã·ãªãŒãºã®èšäºãæžãããšã«ããŸããã
ç§ã¯ããã®ã«ãŒãã«éçºè
ã§ã¯ãªããè·å Žã§ã«ãŒãã«ã³ãŒããäœæããªãããšã«æ³šæããŠãã ããã ããã¯ãã ã®è¶£å³ã§ãã äœã¬ãã«ã®ãã®ã奜ãã§ãããããæãäžããããšã¯è峿·±ãã§ãã ãã®ãããæ··ä¹±ã質å/ã³ã¡ã³ãã衚瀺ãããå Žåã¯ã
Twitterã§
ã¡ãŒã«ããŸãã¯
ãã±ãããäœæããŠãã ããã ãããããã§ãã
ãã¹ãŠã®èšäºã¯
GitHubãªããžããªã§å
¬éãã
ãŠããŸã ãè±èªãèšäºã®å
容ã«åé¡ãããå Žåã¯ãé æ
®ãªããã«ãªã¯ãšã¹ããéä¿¡ããŠãã ããã
ããã¯å
¬åŒã®ããã¥ã¡ã³ãã§ã¯ãªããåã«ãã¬ãŒãã³ã°ãšç¥èã®å
±æã§ããããšã«æ³šæããŠãã ãããå¿
èŠãªç¥è- Cã³ãŒãã«ã€ããŠ
- ã¢ã»ã³ãã©ãŒã³ãŒãã®çè§£ïŒATïŒTæ§æïŒ
ãããã«ãããããªãããã®ãããªããŒã«ãåŠã³å§ããã°ãããªãããã®èšäºãšä»¥äžã®èšäºã§äœãã説æããããšããŸãã ããŠã玹ä»ãçµäºããããLinuxã«ãŒãã«ãšäœã¬ãã«ã®ãã®ã«é£ã³èŸŒãæãæ¥ãŸããã
Linux 3.18ã«ãŒãã«ã®æä»£ã«ãã®æ¬ãæžãå§ããŸãããããã以æ¥å€ãã®ããšãå€ãããŸããã 倿Žãããå Žåã¯ãããã«å¿ããŠèšäºãæŽæ°ããŸãã
éæ³ã®é»æºãã¿ã³ã次ã¯ïŒ
ãããã¯Linuxã«ãŒãã«ã«é¢ããèšäºã§ãããå°ãªããšããã®ã»ã¯ã·ã§ã³ã§ã¯ãŸã å°éããŠããŸããã ã©ããããããŸãã¯ãã¹ã¯ãããã³ã³ãã¥ãŒã¿ãŒã®éæ³ã®é»æºãã¿ã³ãæŒããšãããã«æ©èœãå§ããŸãã ãã¶ãŒããŒãã¯
黿ºã«ä¿¡å·ãéããŸãã ä¿¡å·ãåä¿¡ããåŸãã³ã³ãã¥ãŒã¿ãŒã«å¿
èŠãªé»æ°éãäŸçµŠããŸãã ãã¶ãŒããŒãã
ãPower OKãä¿¡å·ãåä¿¡ãããšããã«ãCPUãèµ·åããããšããŸãã 圌ã¯ãæ®ãã®ãã¹ãŠã®ããŒã¿ãèªåã®ã¬ãžã¹ã¿ãŒã«ãã³ãããããããã«äºåå®çŸ©ãããå€ãèšå®ããŸãã
ããã»ããµ
80386以éã®ããŒãžã§ã³ã§ã¯ãåèµ·ååŸã«CPUã¬ãžã¹ã¿ã«æ¬¡ã®å€ãå«ãŸããŠããå¿
èŠããããŸãã
IP 0xfff0
CSã»ã¬ã¯ã¿ãŒ0xf000
CSããŒã¹0xffff0000
ããã»ããµã¯
ãªã¢ã«ã¢ãŒãã§åäœãå§ã
ãŸã ã å°ãæ»ã£ãŠããã®ã¢ãŒãã®
ã¡ã¢ãªã»ã°ã¡ã³ããŒã·ã§ã³ãçè§£ã
ãŠã¿ãŸãããã ãªã¢ã«ã¢ãŒãã¯ããã¹ãŠã®x86äºæããã»ããµïŒ
8086ããææ°ã®64ãããIntelããã»ããµãŸã§ïŒã§ãµããŒããããŠããŸãã 8086ããã»ããµã¯20ãããã®ã¢ãã¬ã¹ãã¹ã䜿çšããŸããã€ãŸãã
0-0xFFFFF
ãŸãã¯
1
ã¢ãã¬ã¹ç©ºéã§
0-0xFFFFF
ã§ããŸãã ãã ããæå€§ã¢ãã¬ã¹ã
2^16-1
ãŸãã¯
0xffff
ïŒ64ãããã€ãïŒã®16ãããã¬ãžã¹ã¿ãããããŸããã
䜿çšå¯èœãªã¢ãã¬ã¹ç©ºéå
šäœã䜿çšããã«ã¯ã
ã¡ã¢ãªã»ã°ã¡ã³ããŒã·ã§ã³ãå¿
èŠã§ãã ãã¹ãŠã®ã¡ã¢ãªã¯ã
65536
ãã€ãïŒ64 KBïŒã®åºå®ãµã€ãºã®å°ããªã»ã°ã¡ã³ãã«åå²ãããŸãã 16ãããã®ã¬ãžã¹ã¿ã§ã¯64 KBãè¶
ããã¡ã¢ãªã«ã¢ã¯ã»ã¹ã§ããªããããå¥ã®æ¹æ³ãéçºãããŸããã
ã¢ãã¬ã¹ã¯2ã€ã®éšåã§æ§æãããŸãã1ïŒããŒã¹ã¢ãã¬ã¹ãæã€ã»ã°ã¡ã³ãã»ã¬ã¯ã¿ã 2ïŒããŒã¹ã¢ãã¬ã¹ããã®ãªãã»ããã ãªã¢ã«ã¢ãŒãã§ã¯ãã»ã°ã¡ã³ã
* 16
ããŒã¹ã¢ãã¬ã¹ã¯
* 16
ã§ãã ãããã£ãŠãã¡ã¢ãªå
ã®ç©çã¢ãã¬ã¹ãååŸããã«ã¯ãã»ã°ã¡ã³ãã»ã¬ã¯ã¿ãŒã®äžéšã16åããŠãããã«ãªãã»ããã远å ããå¿
èŠããããŸãã
= * 16 +
ããšãã°ã
CS:IP
ã¬ãžã¹ã¿ã®å€ã
0x2000:0x0010
å Žåã察å¿ããç©çã¢ãã¬ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
>>> hex((0x2000 << 4) + 0x0010) '0x20010'
ãã ããæå€§ã»ã°ã¡ã³ãã®ã»ã¬ã¯ã¿ãŒãšãªãã»ãã
0xffff:0xffff
ãååŸãããšãã¢ãã¬ã¹ãååŸãããŸãã
>>> hex((0xffff << 4) + 0xffff) '0x10ffef'
ã€ãŸããæåã®ã¡ã¬ãã€ãã®åŸã®
65520
ãã€ãã§ãã ãªã¢ã«ã¢ãŒãã§ã¯1ã¡ã¬ãã€ããã䜿çšã§ããªããã
ãA20åç·ãç¡å¹ã«
ãããš
0x00ffef
ã¯
0x10ffef
ãªããŸãã
ããŠãããã§ãªã¢ã«ã¢ãŒããšãã®ã¢ãŒãã§ã®ã¡ã¢ãªã¢ãã¬ã¹æå®ã«ã€ããŠå°ãçè§£ã§ããŸããã ãªã»ããåŸã®ã¬ãžã¹ã¿å€ã®èª¬æã«æ»ããŸãã
CS
ã¬ãžã¹ã¿ã¯ãå¯èŠã»ã°ã¡ã³ãã»ã¬ã¯ã¿ãŒãšé衚瀺ã®ããŒã¹ã¢ãã¬ã¹ã®2ã€ã®éšåã§æ§æãããŠããŸãã ããŒã¹ã¢ãã¬ã¹ã¯éåžžãã»ã°ã¡ã³ãã»ã¬ã¯ã¿ã®å€ã«16ãæããããšã§åœ¢æãããŸãããããŒããŠã§ã¢ãªã»ããäžãCSã¬ãžã¹ã¿ã®ã»ã°ã¡ã³ãã»ã¬ã¯ã¿ã¯
0xf000
ã§ãããŒã¹ã¢ãã¬ã¹ã¯
0xffff0000
ã§ãã ããã»ããµã¯ãCSã倿ŽããããŸã§ãã®ç¹å¥ãªããŒã¹ã¢ãã¬ã¹ã䜿çšããŸãã
éå§ã¢ãã¬ã¹ã¯ãEIPã¬ãžã¹ã¿ã®å€ã«ããŒã¹ã¢ãã¬ã¹ã远å ããããšã«ãã圢æãããŸãã
>>> 0xffff0000 + 0xfff0 '0xfffffff0'
0xfffffff0
ãååŸããŸããããã¯ã4 GBæªæºã®16ãã€ãã§ãã ãã®ç¹ã
ãªã»ãããã¯ãã«ãšåŒã³ãŸãã ããã¯ããªã»ããåŸã«CPUãæåã®åœä»€ã®å®è¡ãåŸ
ã€ã¡ã¢ãªå
ã®å Žæã§ãããžã£ã³ãæäœïŒ
jmp ïŒã¯ãéåžžBIOSãšã³ããªãã€ã³ãã瀺ããŸãã ããšãã°ã
corebootã®ãœãŒã¹ã³ãŒãïŒ
src/cpu/x86/16bit/reset16.inc
ïŒãèŠããšã次ã®ããã«è¡šç€ºãããŸãã
.section ".reset", "ax", %progbits .code16 .globl _start _start: .byte 0xe9 .int _start16bit - ( . + 2 ) ...
ããã§ã¯ããªãã¬ãŒã·ã§ã³ã³ãŒãïŒ
opcode ïŒ
jmp
ãã€ãŸã
0xe9
ã衚瀺ãããå®å
ã¢ãã¬ã¹
_start16bit - ( . + 2)
ã§ãã
ãŸãã
reset
ã»ã¯ã·ã§ã³ã¯16ãã€ãã§ãããã¢ãã¬ã¹
0xfffff0
ïŒ
src/cpu/x86/16bit/reset16.ld
ïŒããå®è¡ããããã«ã³ã³ãã€ã«ãããŠããããšã
0xfffff0
ãŸãã
SECTIONS { _bogus = ASSERT(_start16bit >= 0xffff0000, "_start16bit too low. Please report."); _ROMTOP = 0xfffffff0; . = _ROMTOP; .reset . : { *(.reset); . = 15; BYTE(0x00); } }
BIOSãèµ·åããŸãã BIOSããŒããŠã§ã¢ãåæåããŠç¢ºèªããåŸãããŒãããã€ã¹ãèŠã€ããå¿
èŠããããŸãã èµ·åé åºã¯BIOSèšå®ã«ä¿åãããŸãã ããŒããã©ã€ãããèµ·åããããšãããšãBIOSã¯ããŒãã»ã¯ã¿ãŒãèŠã€ããããšããŸãã
MBRããŒãã£ã·ã§ã³ãã£ã¹ã¯ã§ã¯ãããŒãã»ã¯ã¿ãŒã¯æåã®ã»ã¯ã¿ãŒã®æåã®446ãã€ãã«æ ŒçŽãããŸããåã»ã¯ã¿ãŒã¯512ãã€ãã§ãã æåã®ã»ã¯ã¿ãŒã®æåŸã®2ãã€ãã¯
0x55
ãš
0xaa
ã§ãã BIOSãèµ·åããã€ã¹ã§ããããšã瀺ããŠããŸãã
äŸïŒ
; ; : Intel x86 ; [BITS 16] boot: mov al, '!' mov ah, 0x0e mov bh, 0x00 mov bl, 0x07 int 0x10 jmp $ times 510-($-$$) db 0 db 0x55 db 0xaa
åéããŠå®è¡ããŸãïŒ
nasm -f bin boot.nasm && qemu-system-x86_64 boot
QEMUã¯ãäœæããã°ããã®
boot
ãã€ããªããã£ã¹ã¯ã€ã¡ãŒãžãšããŠäœ¿çšããã³ãã³ããåãåã
boot
ã äžèšã§çæããããã€ããªãã¡ã€ã«ã¯ãããŒãã»ã¯ã¿ã®èŠä»¶ïŒ
0x7c00
ããå§ãŸããããžãã¯ã·ãŒã±ã³ã¹ã§çµããïŒãæºãããããQEMUã¯ãã€ããªããã£ã¹ã¯ã€ã¡ãŒãžã®ãã¹ã¿ãŒããŒãã¬ã³ãŒãïŒMBRïŒãšèŠãªããŸãã
衚瀺ãããŸãïŒ

ãã®äŸã§ã¯ãã³ãŒãã16ãããã®ãªã¢ã«ã¢ãŒãã§
0x7c00
ããã¡ã¢ãªã®ã¢ãã¬ã¹
0x7c00
ããéå§ããããšã
0x7c00
ãŸãã éå§åŸã
0x10å²ã蟌ã¿ãçºçããåã«æåãåºåãããŸã
!
; æ®ãã®510ãã€ãããŒãã§åãã2ã€ã®ããžãã¯ãã€ã
0xaa
ãš
0x55
çµäºããŸãã
objdump
ãŠãŒãã£ãªãã£ã䜿çšããŠãã€ããªãã³ãã衚瀺ã§ããŸãã
nasm -f bin boot.nasm
objdump -D -b binary -mi386 -Maddr16,data16,intel boot
ãã¡ãããå®éã®ããŒãã»ã¯ã¿ãŒã«ã¯ããŒãã®æãšæå笊ã®ä»£ããã«ãããŒãããã»ã¹ãšããŒãã£ã·ã§ã³ããŒãã«ãç¶ç¶ããã³ãŒãããããŸã:)ã ãã®ç¬éãããBIOSã¯ããŒãããŒããŒã«å¶åŸ¡ãæž¡ããŸãã
泚 ïŒäžèšã§èª¬æããããã«ãCPUã¯ãªã¢ã«ã¢ãŒãã§ãã ã¡ã¢ãªå
ã®ç©çã¢ãã¬ã¹ã®èšç®ã¯æ¬¡ã®ãšããã§ãã
= * 16 +
16ãããã®æ±çšã¬ãžã¹ã¿ã®ã¿ãããã16ãããã¬ãžã¹ã¿ã®æå€§å€ã¯
0xffff
ã§ãããããæå€§å€ã§ã®çµæã¯æ¬¡ã®ããã«ãªããŸãã
>>> hex((0xffff * 16) + 0xffff) '0x10ffef'
ããã§ã
0x10ffef
ã¯
1 + 64 - 16
ã§ãã
8086ããã»ããµ ïŒãªã¢ã«ã¢ãŒããåããæåã®ããã»ããµïŒã«ã¯ã20ãããã®ã¢ãã¬ã¹è¡ããããŸãã
2^20 = 1048576
ã§ãããããå®éã«å©çšå¯èœãªã¡ã¢ãªã¯1 MBã§ãã
äžè¬ã«ããªã¢ã«ã¢ãŒãã¡ã¢ãªã®ã¢ãã¬ã¹æå®ã¯æ¬¡ã®ãšããã§ãã
0x00000000-0x000003FF-ãªã¢ã«ã¢ãŒãã®å²ã蟌ã¿ãã¯ã¿ãŒã®ããŒãã«
0x00000400-0x000004FF-BIOSããŒã¿é å
0x00000500-0x00007BFF-䜿çšãããŠããŸãã
0x00007C00-0x00007DFF-ããŒãããŒããŒ
0x00007E00-0x0009FFFF-䜿çšãããŠããŸãã
0x000A0000-0x000BFFFF-ãããªRAMïŒVRAMïŒ
0x000B0000-0x000B7777-ã¢ãã¯ããããªã¡ã¢ãª
0x000B8000-0x000BFFFF-ã«ã©ãŒã¢ãŒããããªã¡ã¢ãª
0x000C0000-0x000C7FFF-ãããªROM BIOS
0x000C8000-0x000EFFFF-ã·ã£ããŠãšãªã¢ïŒBIOSã·ã£ããŠïŒ
0x000F0000-0x000FFFFF-ã·ã¹ãã BIOS
èšäºã®åé ã§ãããã»ããµã®æåã®åœä»€ã¯
0xFFFFFFF0
ã«ãããããã¯
0xFFFFF
ïŒ1 MBïŒãããã¯ããã«å€§ãããšæžãããŠããŸãã CPUã¯ãªã¢ã«ã¢ãŒãã§ãã®ã¢ãã¬ã¹ã«ã©ã®ããã«ã¢ã¯ã»ã¹ã§ããŸããïŒ
corebootããã¥ã¡ã³ãã®åçïŒ
0xFFFE_0000 - 0xFFFF_FFFF: 128 ROM
å®è¡ã®éå§æã«ã¯ãBIOSã¯RAMã§ã¯ãªãROMã«ãããŸãã
ããŒãããŒããŒ
Linuxã«ãŒãã«ã¯ã
GRUB 2ã
syslinuxãªã©ã®ããŸããŸãªããŒãããŒããŒã§ããŒãã§ããŸãã ã«ãŒãã«ã«ã¯ãLinuxãµããŒããå®è£
ããããã®ããŒãããŒããŒèŠä»¶ãå®çŸ©ããããŒããããã³ã«ããããŸãã ãã®äŸã§ã¯ãGRUB 2ã䜿çšããŠããŸãã
ããŒãããã»ã¹ãç¶è¡ãããšãBIOSã¯ããŒãããã€ã¹ãéžæããå¶åŸ¡ãããŒãã»ã¯ã¿ãŒã«è»¢éããå®è¡ã¯
boot.imgã§å§ãŸããŸãã ãµã€ãºãéãããŠãããããããã¯éåžžã«åçŽãªã³ãŒãã§ãã ã¡ã€ã³ã®GRUB 2ã€ã¡ãŒãžã«ç§»åããããã®ãã€ã³ã¿ãŒãå«ãŸããŠããã
diskboot.imgã§å§ãŸããéåžžã¯æåã®ããŒãã£ã·ã§ã³ã®åã®æªäœ¿çšã¹ããŒã¹ã®æåã®ã»ã¯ã¿ãŒã®çŽåŸã«ä¿åãããŸãã äžèšã®ã³ãŒãã¯ããã¡ã€ã«ã·ã¹ãã ãåŠçããããã®GRUB 2ã«ãŒãã«ãšãã©ã€ããŒãå«ãæ®ãã®ã€ã¡ãŒãžãã¡ã¢ãªã«ããŒãããŸãã ãã®åŸã
grub_main颿°ã
å®è¡ãããŸãã
grub_main
颿°ã¯ãã³ã³ãœãŒã«ãåæåããã¢ãžã¥ãŒã«ã®ããŒã¹ã¢ãã¬ã¹ãè¿ããã«ãŒãããã€ã¹ãèšå®ããgrubæ§æãã¡ã€ã«ãããŒã/è§£æããã¢ãžã¥ãŒã«ãããŒãããŸãã å®è¡ã®æåŸã«ãgrubãéåžžã¢ãŒãã«ããŸãã
grub_normal_execute
颿°ïŒ
grub-core/normal/main.c
ãœãŒã¹ãã¡ã€ã«ããïŒã¯ãæåŸã®æºåãå®äºãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãéžæããããã®ã¡ãã¥ãŒã衚瀺ããŸãã grubã¡ãã¥ãŒé
ç®ã®1ã€ãéžæãããšã
grub_menu_execute_entry
颿°ã
boot
ããã«ãããgrub
boot
ã³ãã³ããå®è¡ãããéžæããOSãããŒããããŸãã
ã«ãŒãã«ããŒããããã³ã«ã§ç€ºãããŠããããã«ãããŒãããŒããŒã¯ã«ãŒãã«ã€ã³ã¹ããŒã«ããããŒã®ããã€ãã®ãã£ãŒã«ããèªã¿åããå
¥åããå¿
èŠããããŸãã
0x01f1
ã¯ãã«ãŒãã«ã€ã³ã¹ããŒã«ã³ãŒãããã®ãªãã»ãã
0x01f1
ããå§ãŸããŸãã ãã®ãªãã»ããã¯ã
ãªã³ã«ã¹ã¯ãªããã«ç€ºãããŠã
ãŸã ã ã«ãŒãã«ããããŒ
arch / x86 / boot / header.Sã¯
次ã§å§ãŸã
ãŸã ïŒ
.globl hdr hdr: setup_sects: .byte 0 root_flags: .word ROOT_RDONLY syssize: .long 0 ram_size: .word 0 vid_mode: .word SVGA_MODE root_dev: .word 0 boot_flag: .word 0xAA55
ããŒãããŒããŒã¯ããã®ããããŒãšä»ã®ããããŒïŒãã®äŸã®ããã«LinuxããŒããããã³ã«ã§ã¿ã€ã
write
ãšããŠã®ã¿ããŒã¯ãããŠããïŒãã³ãã³ãã©ã€ã³ããåãåã£ãå€ãŸãã¯ããŒãæã«èšç®ããå€ã§åããå¿
èŠããããŸãã ããã§ããã¹ãŠã®ããããŒãã£ãŒã«ãã®èª¬æãšèª¬æã«ã€ããŠã¯èª¬æããŸããã ã«ãŒãã«ãããããã©ã®ããã«äœ¿çšãããã«ã€ããŠã¯åŸã§èª¬æããŸãã ãã¹ãŠã®ãã£ãŒã«ãã®èª¬æã«ã€ããŠã¯
ãããŠã³ããŒããããã³ã«ãåç
§ããŠãã ããã
ã«ãŒãã«ããŒããããã³ã«ã§ç¢ºèªã§ããããã«ãã¡ã¢ãªã¯æ¬¡ã®ããã«è¡šç€ºãããŸãã
| ä¿è·ãããã«ãŒãã«ã¢ãŒã|
100000 + ------------------------ +
| I / Oãããã³ã°|
0A0000 + ------------------------ +
| äºå BIOSã®å Žå| å¯èœãªéãç¡æã§æ®ã
ãã
| ã³ãã³ãã©ã€ã³| ïŒX + 10000æªæºã®å ŽåããããŸãïŒ
X + 10000 + ------------------------ +
| ã¹ã¿ãã¯/ããŒã| å®éã®ã«ãŒãã«ã¢ãŒãã³ãŒãã䜿çšããã«ã¯
X + 08000 + ------------------------ +
| ã«ãŒãã«ã®ã€ã³ã¹ããŒã«| å®éã®ã«ãŒãã«ã¢ãŒãã³ãŒã
| ã«ãŒãã«ããŒãã»ã¯ã¿ãŒ| ã¬ã¬ã·ãŒã«ãŒãã«ããŒãã»ã¯ã¿ãŒ
X + ------------------------ +
| ããŒããŒ| <-ãšã³ããªãã€ã³ã0x7C00ããŒãã»ã¯ã¿
001000 + ------------------------ +
| äºå MBR / BIOSã®å Žå|
000800 + ------------------------ +
| éåžžäœ¿çš MBR |
000600 + ------------------------ +
| äžå€ BIOSã®ã¿|
000000 + ------------------------ +
ãã®ãããããŒããŒãå¶åŸ¡ãã«ãŒãã«ã«è»¢éãããšããæ¬¡ã®ã¢ãã¬ã¹ã§éå§ããŸãã
X + sizeof (KernelBootSector) + 1
X
ã¯ã«ãŒãã«ããŒãã»ã¯ã¿ã®ã¢ãã¬ã¹ã§ãã ãã®äŸã§ã¯ãã¡ã¢ãªãã³ãã«èŠãããããã«ã
X
ã¯
0x10000
ã§ãã

ããŒãããŒããŒã¯Linuxã«ãŒãã«ãã¡ã¢ãªã«ç§»åããããããŒãã£ãŒã«ãã«å
¥åããŠããã察å¿ããã¡ã¢ãªã¢ãã¬ã¹ã«ç§»åããŸããã ããã§ãã«ãŒãã«ã®ã€ã³ã¹ããŒã«ã³ãŒãã«çŽæ¥ã¢ã¯ã»ã¹ã§ããŸãã
ã«ãŒãã«ã€ã³ã¹ããŒã«ãã§ãŒãºã®éå§
æåŸã«ãç§ãã¡ã¯äžå¿ã«ããŸãïŒ æè¡çã«ã¯ãŸã å®è¡ãããŠããŸããã ãŸããã«ãŒãã«ã®ã€ã³ã¹ããŒã«éšåã§ã¯ãè§£åããã°ã©ã ãã¡ã¢ãªç®¡çãå«ããã®ãªã©ãäœããæ§æããå¿
èŠããããŸãã ãã®ãã¹ãŠã®åŸãåœŒå¥³ã¯æ¬åœã®ã³ã¢ã鿢±ããŠããã«è¡ããŸãã ã€ã³ã¹ããŒã«ã¯ã
_startæåã
䜿çšããŠ
arch / x86 / boot / header.Sã§éå§ãã
ãŸã ã
äžèŠãããšãããã¯å°ãå¥åŠã«èŠãããããããŸããã圌ã®åã«ã¯ããã€ãã®æç€ºããããŸãã ããããæãLinuxã«ãŒãã«ã«ã¯ç¬èªã®ããŒãããŒããŒããããŸããã ããšãã°ãå®è¡ãããšã
qemu-system-x86_64 vmlinuz-3.18-generic
衚瀺ãããŸãïŒ

å®éã
header.S
ãã¡ã€ã«ã¯ãããžãã¯ãã³ããŒ
MZ ïŒäžèšã®ãã³ãã®ã¹ã¯ãªãŒã³ã·ã§ãããåç
§ïŒããšã©ãŒã¡ãã»ãŒãžã®ããã¹ããããã³
PEããããŒã§å§ãŸããŸãã
#ifdef CONFIG_EFI_STUB # "MZ", MS-DOS header .byte 0x4d .byte 0x5a #endif ... ... ... pe_header: .ascii "PE" .word 0
UEFIãµããŒãã®ãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãããŒãããå¿
èŠããããŸãã æ¬¡ã®ç« ã§ãã®ããã€ã¹ãæ€èšããŸãã
ã«ãŒãã«ãã€ã³ã¹ããŒã«ããããã®å®éã®ãšã³ããªãã€ã³ãïŒ
ããŒããŒïŒgrub2ãªã©ïŒã¯ãã®ãã€ã³ãïŒ
MZ
ããã®ãªãã»ãã
0x200
ïŒãç¥ã£ãŠããã
header.S
çŽæ¥
header.S
ãŸããã
.bstext
ã¯
.bstext
ã»ã¯ã·ã§ã³ã§å§ãŸãããšã©ãŒã¡ãã»ãŒãžã®ããã¹ãããããŸãïŒ
// // arch/x86/boot/setup.ld // . = 0; // current position .bstext : { *(.bstext) } // put .bstext section to position 0 .bsdata : { *(.bsdata) }
ã«ãŒãã«ã€ã³ã¹ããŒã«ãšã³ããªãã€ã³ãïŒ
.globl _start _start: .byte 0xeb .byte start_of_setup-1f 1:
ããã«ãªãã¬ãŒã·ã§ã³ã³ãŒã
jmp
ïŒ
0xeb
ïŒããããããã¯ãã€ã³ã
start_of_setup-1f
ãŸãã ããšãã°ã
Nf
衚èšã§ã¯ã
2f
ã¯ããŒã«ã«ã©ãã«
2:
æã
2:
ãã®äŸã§ã¯ãããã¯ã©ãã«
1
ã§ãããé·ç§»çŽåŸã«ååšããã»ããã¢ããããããŒã®æ®ããå«ã¿ãŸãã ã€ã³ã¹ããŒã«ããããŒã®çŽåŸã«ã
start_of_setup
ã©ãã«ã§å§ãŸã
.entrytext
ã»ã¯ã·ã§ã³ããããŸãã
ããã¯ãå®éã«å®è¡ãããæåã®ã³ãŒãã§ãïŒãã¡ããã以åã®ãžã£ã³ãåœä»€ä»¥å€ïŒã ã«ãŒãã«ã®ã€ã³ã¹ããŒã«ã®äžéšãããŒããŒããå¶åŸ¡ãåãåã£ãåŸãæåã®
jmp
åœä»€ã¯ãå®éã®ã«ãŒãã«ã¢ãŒãã®å
é ãããã€ãŸãæåã®512ãã€ãã®åŸã®ãªãã»ãã
0x200
é
眮ãããŸãã ããã¯ãLinuxã«ãŒãã«ããŒããããã³ã«ãšgrub2ãœãŒã¹ã³ãŒãã®äž¡æ¹ã§ç¢ºèªã§ããŸãã
segment = grub_linux_real_target >> 4; state.gs = state.fs = state.es = state.ds = state.ss = segment; state.cs = segment + 0x20;
ãã®å Žåãã«ãŒãã«ã¯
0x10000
èµ·åããŸãã ããã¯ãã«ãŒãã«ã®ã€ã³ã¹ããŒã«ãéå§ããåŸãã»ã°ã¡ã³ãã¬ãžã¹ã¿ã次ã®å€ãæã€ããšãæå³ããŸãã
gs = fs = es = ds = ss = 0x10000
cs = 0x10200
start_of_setup
é²ãã åŸ
start_of_setup
ã«ãŒãã«ã¯æ¬¡ã®ããšãè¡ãå¿
èŠããããŸãã
- ãã¹ãŠã®ã»ã°ã¡ã³ãã¬ãžã¹ã¿å€ãåãã§ããããšã確èªããŠãã ãã
- å¿
èŠã«å¿ããŠãæ£ããã¹ã¿ãã¯ãæ§æããŸã
- bssãæ§æãã
- arch / x86 / boot / main.cã® Cã³ãŒãã«ç§»åããŸã
ãããã©ã®ããã«å®è£
ãããŠãããèŠãŠã¿ãŸãããã
ã»ã°ã¡ã³ãã±ãŒã¹ã¢ã©ã€ã¡ã³ã
ãŸããã«ãŒãã«ã¯
ds
ããã³
es
ã»ã°ã¡ã³ãã¬ãžã¹ã¿ãåãã¢ãã¬ã¹ãæããŠããããšã確èªããŸãã æ¬¡ã«ã
cld
ã䜿çšããŠæ¹åãã©ã°ãã¯ãªã¢ããŸãã
movw %ds, %ax movw %ax, %es cld
å
ã»ã©æžããããã«ãgrub2ã¯ããã©ã«ãã§ã«ãŒãã«ã€ã³ã¹ããŒã«ã³ãŒãã
0x10000
ã«ã
cs
ã
0x10200
ããŸããããã¯ããã¡ã€ã«ã®å
é ããã§ã¯ãªããããããã®é·ç§»ããå®è¡ãéå§ãããããã§ãã
_start: .byte 0xeb .byte start_of_setup-1f
ããã¯ã
4d 5aããã®
512
ãã€ãã®ãªãã»ããã§ãã ä»ã®ãã¹ãŠã®ã»ã°ã¡ã³ãã¬ãžã¹ã¿ãšåæ§ã«ã
cs
ã
0x10200
ãã
0x10000
ã«æããå¿
èŠããããŸãã ãã®åŸãã¹ã¿ãã¯ãã€ã³ã¹ããŒã«ããŸãã
pushw %ds pushw $6f lretw
ãã®åœä»€ã¯ã
ds
å€ãã¹ã¿ãã¯ã«ããã·ã¥ãããã®åŸã«ã©ãã«
6ã®ã¢ãã¬ã¹ãš
lretw
åœä»€ã
lretw
ãŸã
lretw
åœä»€ã¯ãã©ãã«
6
ã®ã¢ãã¬ã¹ã
ã³ãã³ãã«ãŠã³ã¿ãŒã®ã¬ãžã¹ã¿ã«ããŒãããå€
ds
cs
ããŒãããŸãã ãã®åŸã
ds
ãš
cs
ã¯åãå€ã«ãªããŸãã
ã¹ã¿ãã¯èšå®
ãã®ã³ãŒãã®ã»ãšãã©ãã¹ãŠã¯ããªã¢ã«ã¢ãŒãã§Cç°å¢ãæºåããããã»ã¹ã®äžéšã§ãã æ¬¡ã®æé ã¯ã
ss
ã¬ãžã¹ã¿å€ã確èªãã
ss
å€ãæ£ãããªãå Žåã«æ£ããã¹ã¿ãã¯ãäœæããããšã§ãã
movw %ss, %dx cmpw %ax, %dx movw %sp, %dx je 2f
ããã«ããã3ã€ã®ç°ãªãã·ããªãªãããªã¬ãŒãããŸãã
ss
æå¹ãªå€ã¯0x1000
ïŒ cs
ãé€ãä»ã®ãã¹ãŠã®ã¬ãžã¹ã¿ãšåæ§ïŒss
ç¡å¹ãªå€ãããã CAN_USE_HEAP
ãã©ã°CAN_USE_HEAP
èšå®ãããŠããŸãïŒä»¥äžãåç
§ïŒss
ç¡å¹ãªå€ãããã CAN_USE_HEAP
ãã©ã°CAN_USE_HEAP
èšå®ãããŠããŸããïŒä»¥äžãåç
§ïŒ
ãã¹ãŠã®ã·ããªãªãé çªã«æ€èšããŠãã ããã
ss
æå¹ãªå€ïŒ 0x1000
ïŒããããŸãã ãã®å Žåãã©ãã«2ã«é²ã¿ãŸãã
2: andw $~3, %dx jnz 3f movw $0xfffc, %dx 3: movw %ax, %ss movzwl %dx, %esp sti
ããã§ã¯ã
dx
ã¬ãžã¹ã¿ïŒããŒãããŒããŒã«ãã£ãŠç€ºããã
sp
å€ãå«ãïŒã®ã¢ã©ã€ã¡ã³ãã
4
ãã€ãã«èšå®ãããŒãããã§ãã¯ããŸãã ãŒãã®å Žåãå€
0xfffc
dx
ïŒæå€§ã»ã°ã¡ã³ããµã€ãº64 KBã®åã«
4
ãã€ãã§æŽåãããã¢ãã¬ã¹ïŒãå
¥åããŸãã ãŒãã«çãããªãå ŽåãããŒãããŒããŒã§æå®ããã
sp
å€ïŒãã®å Žåã¯
0xf7f4
ïŒãåŒãç¶ã䜿çšããŸãã æ¬¡ã«ã
ss
ã«
ax
å€ãå
¥åããŸããããã«ãããæ£ããã»ã°ã¡ã³ãã¢ãã¬ã¹
0x1000
ãä¿åãããæ£ãã
sp
èšå®ãããŸãã ããã§æ£ããã¹ã¿ãã¯ãã§ããŸããã

- 2çªç®ã®ã·ããªãªã§ã¯ã
ss != ds
ã§ãã ãŸããå€_end ïŒã€ã³ã¹ããŒã«ã³ãŒãã®çµäºã¢ãã¬ã¹ïŒãdx
loadflags
ã testb
åœä»€ã䜿çšããŠããããŒãã£ãŒã«ãloadflags
ããã§ãã¯ããããŒãã䜿çšã§ãããã©ããããã§ãã¯ããŸãã loadflagsã¯ã次ã®ããã«å®çŸ©ãããããããã¹ã¯ããããŒã§ãã
#define LOADED_HIGH (1<<0) #define QUIET_FLAG (1<<5) #define KEEP_SEGMENTS (1<<6) #define CAN_USE_HEAP (1<<7)
ãããŠãããŒããããã³ã«ã«ç€ºãããŠããããã«ïŒ
: loadflags
.
7 (): CAN_USE_HEAP
1, ,
heap_end_ptr . ,
.
CAN_USE_HEAP
ãããã
CAN_USE_HEAP
å Žåã
dx
ã§å€
heap_end_ptr
ïŒ
_end
ãæãïŒãèšå®ããããã«
STACK_SIZE
ã远å ããŸãïŒæå°ã¹ã¿ãã¯ãµã€ãºã¯
1024
ãã€ãã§ãïŒã ãã®åŸãã©ãã«
2
ã«ç§»åãïŒåã®å Žåãšåæ§ïŒãæ£ããã¹ã¿ãã¯ãäœæããŸãã

CAN_USE_HEAP
èšå®ãããŠããªãå ŽåCAN_USE_HEAP
ã _end
ãã_end + STACK_SIZE
ãŸã§ã®æå°ã¹ã¿ãã¯ã䜿çšããŸãã

BSSã»ããã¢ãã
ã¡ã€ã³Cã³ãŒãã«é²ãåã«ãããã«2ã€ã®ã¹ããããå¿
èŠã§ããããã¯ã
BSSãšãªã¢ãã»ããã¢ãããããããžãã¯ã眲åãæ€èšŒããããšã§ãã æåã«çœ²åæ€èšŒïŒ
cmpl $0x5a5aaa55, setup_sig jne setup_bad
ãã®åœä»€ã¯ãåã«
setup_sigãšããžãã¯çªå·0x5a5aaa55ãæ¯èŒããŸãã ããããçãããªãå ŽåãèŽåœçãªãšã©ãŒãå ±åãããŸãã
ããžãã¯ãã³ããŒãåãã§ãæ£ããã»ã°ã¡ã³ãã¬ãžã¹ã¿ã®ã»ãããšã¹ã¿ãã¯ãããå ŽåãCã³ãŒãã«é²ãåã«BSSã»ã¯ã·ã§ã³ãæ§æããããã ãã«æ®ããŸãã
BSSã»ã¯ã·ã§ã³ã¯ãéçã«å²ãåœãŠãããåæåãããŠããªãããŒã¿ãæ ŒçŽããããã«äœ¿çšãããŸãã Linuxã¯ããã®ã¡ã¢ãªé åããªã»ãããããŠããããšãæ
éã«ãã§ãã¯ããŸãã
movw $__bss_start, %di movw $_end+3, %cx xorl %eax, %eax subw %di, %cx shrw $2, %cx rep; stosl
ãŸããéå§ã¢ãã¬ã¹
__bss_startã di
ç§»åããŸãã æ¬¡ã«ãã¢ãã¬ã¹
_end + 3
ïŒ4ãã€ãã®ã¢ã©ã€ã¡ã³ãã§+3ïŒã
cx
ç§»åãããŸãã
eax
ã¬ãžã¹ã¿ãã¯ãªã¢ããïŒ
xor
åœä»€ã䜿çšïŒãbssïŒ
cx-di
ïŒã»ã¯ã·ã§ã³ã®ãµã€ãºãèšç®ããã
cx
é
眮ãããŸãã æ¬¡ã«ã
cx
ã¯4ã€ã«åå²ããïŒãã¯ãŒããã®ãµã€ãºïŒã
stosl
åœä»€ã
stosl
䜿çšã
stosl
ã
di
æãã¢ãã¬ã¹ã«å€
ïŒãŒãïŒãæ ŒçŽããèªåçã«
di
ã4å¢ããã
ããŒãã«ãªããŸã§ãããç¹°ãè¿ããŸãã ãã®ã³ãŒãã®æçµçãªå¹æã¯ãã¡ã¢ãªå
ã®ãã¹ãŠã®ã¯ãŒãã«
__bss_start
ãã
_end
ãŸã§ãŒããæžã蟌ãŸããããšã§ãïŒ

ã¡ã€ã³ã«ç§»å
ããã ãã§ãïŒã¹ã¿ãã¯ãšBSSãããã®ã§ã
main()
C颿°ã«ç§»åã§ããŸãïŒ
calll main
main()
颿°ã¯
arch / x86 / boot / main.cã«ãããŸãã æ¬¡ã®ããŒãã§åœŒå¥³ã«ã€ããŠè©±ããŸãã
ãããã«
ããã§ãLinuxã«ãŒãã«ããã€ã¹ã«é¢ããæåã®ããŒãã¯çµããã§ãã
質åãææ¡ãããå Žåã¯ãTwitterã§ã¡ãŒã«ããŸãã¯ãã±ãããäœæããŠãã ãããæ¬¡ã®éšåã§ã¯ãæã
ã¯ãLinuxã«ãŒãã«ãã¡ã¢ãªãªã©ã®ãµãããã°ã©ã ã®å®è£
ã®ã€ã³ã¹ããŒã«äžã«å®è¡ãããCã®æåã®ã³ãŒãã衚瀺ãããŸãmemset
ãmemcpy
ãearlyprintk
ãæ©æå®æœãšãã³ã³ãœãŒã«ã®åæåãããã³å€ãããåç
§è³æ