PCIãã¹ãããŒãªã³ã°ããã¡ã«ããºã ã説æããŠããèšäºã§ã¯ãæãéèŠãªããšã¯è©³çްã«èª¬æãããŠããŸããã§ãããå®éã®ããŒããŠã§ã¢ã§ãã®ã³ãŒããå®è¡ããæ¹æ³ã§ããïŒ ç¬èªã®ããŒããã£ã¹ã¯ãäœæããæ¹æ³ã¯ïŒ ãã®èšäºã§ã¯ãããããã¹ãŠã®è³ªåã«è©³çްã«åçããŸãïŒéšåçã«ã¯ããããã®åé¡ã«ã€ããŠã¯åã®èšäºã§èª¬æããŸããããèªã¿ãããããããã«ãè³æã®éè€ãå°ãèš±å¯ããŸãïŒã
ã€ã³ã¿ãŒãããã«ã¯ãäœçŸãã®æ¢è£œã®å°ããªè¶£å³OSãååšããå Žåã§ããç¬èªã®ããOSãäœæããæ¹æ³ã«é¢ããå€ãã®èª¬æãšãã¥ãŒããªã¢ã«ããããŸãã ãã®ããŒãã«é¢ããæã䟡å€ã®ãããªãœãŒã¹ã®1ã€ã¯ãosdev.orgããŒã¿ã«ã§ãã PCIã«é¢ãã以åã®èšäºïŒããã³ææ°ã®OSã«ååšããããŸããŸãªæ©èœã«é¢ããåŸç¶ã®èšäºãäœæããæ©èœïŒãè£è¶³ããããã«ãCã®éåžžã®ããã°ã©ã ã䜿çšããŠããŒããã£ã¹ã¯ãäœæããæé ãã¹ãããããšã«èª¬æããŸããèªåã§æŽçããŠãã ããã
ãã®ãããç®æšã¯ãã§ããã ãå°ãªãåŽåã§ãç¬èªã®èµ·åå¯èœãªUSBãã©ãã·ã¥ãã©ã€ããäœæããŸããããã«ãããã³ã³ãã¥ãŒã¿ãŒç»é¢ã«å€å
žçãªãHello Worldããå°å·ãããŸãã
ããæ£ç¢ºã«ã¯ãããŒãžã®ã¢ãã¬ã¹æå®ãšå²ã蟌ã¿ãç¡å¹ã«ããŠä¿è·ã¢ãŒãã«ãå
¥ããå¿
èŠããããŸããããã¯ãåçŽãªã³ã³ãœãŒã«ããã°ã©ã ã®éåžžã®åäœã䌎ãæãåçŽãªããã»ããµã¢ãŒãã§ãã ãã®ç®æšãéæããæãåççãªæ¹æ³ã¯ããã«ãããŒã圢åŒããµããŒãããã«ãŒãã«ãæ§ç¯ããäžè¬çãªGrubããŒãããŒããŒã䜿çšããŠããŒãããããšã§ãã ãã®ãœãªã¥ãŒã·ã§ã³ã«ä»£ããæ¹æ³ã¯ãç¬èªã®ããªã¥ãŒã ããŒãã¬ã³ãŒãïŒVBRïŒãèšè¿°ããããšã§ããããã«ãããç¬èªã®ããŒããŒïŒããŒããŒïŒãããŒããããŸãã å°ãªããšããŸãšããªããŒãããŒããŒã¯ããã£ã¹ã¯ããã¡ã€ã«ã·ã¹ãã ãããã³elfã€ã¡ãŒãžãè§£æã§ããå¿
èŠããããŸãã ã€ãŸãã倧éã®ã¢ã»ã³ãã©ã³ãŒããšå€§éã®Cã³ãŒããèšè¿°ããå¿
èŠããããŸããèŠããã«ãå¿
èŠãªãã¹ãŠã®æ¹æ³ãæ¢ã«ç¥ã£ãŠããGrubã䜿çšããæ¹ãç°¡åã§ãã
æåã«ãç¹å®ã®ã³ã³ãã€ã©ãšãŠãŒãã£ãªãã£ã®ã»ããããããªãã¢ã¯ã·ã§ã³ã«å¿
èŠã§ãã æãç°¡åãªæ¹æ³ã¯ãäœããã®çš®é¡ã®LinuxïŒUbuntuãªã©ïŒã䜿çšããããšã§ããããã«ã¯ãããŒãå¯èœãªãã©ãã·ã¥ãã©ã€ããäœæããããã«å¿
èŠãªãã®ããã¹ãŠå«ãŸããŠããããã§ãã Windowsã§ã®äœæ¥ã«æ
£ããŠããå Žåã¯ãLinuxã§ä»®æ³ãã·ã³ãæ§æã§ããŸãïŒVirtual BoxãŸãã¯VMware Workstationã䜿çšïŒã
Linux Ubuntuã䜿çšããŠããå Žåãæåã«ããã€ãã®ãŠãŒãã£ãªãã£ãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã
1.ã°ã©ãã ãããè¡ãã«ã¯ã次ã®ã³ãã³ãã䜿çšããŸãã
sudo apt-get install grub
2. Qemuã ãã¹ãŠããã°ãã
ãã¹ãããã³ãããã°ããå¿
èŠã
ãããŸãããã®ãããã³ãã³ãã¯äŒŒãŠããŸãã
sudo apt-get install qemu
ããã§ãèšç»ã¯æ¬¡ã®ããã«ãªããŸãã
1.ç»é¢ã«è¡ãå°å·ããCããã°ã©ã ãäœæããŸãã
2.ããããããããŒã圢åŒã®ã€ã¡ãŒãžïŒkernel.binïŒãã³ã³ãã€ã«ããGRUBã䜿çšããŠããŠã³ããŒãã§ããããã«ããŸãã
3.ããŒããã£ã¹ã¯ã€ã¡ãŒãžãã¡ã€ã«ãäœæãããã©ãŒãããããŸãã
4.ãã®ã€ã¡ãŒãžã«Grubãã€ã³ã¹ããŒã«ããŸãã
5.äœæããããã°ã©ã ïŒkernel.binïŒããã£ã¹ã¯ã«ã³ããŒããŸãã
6.ã€ã¡ãŒãžãç©çã¡ãã£ã¢ã«æžã蟌ãããqemuã§å®è¡ããŸãã
ããã³ã·ã¹ãã ã®èµ·åããã»ã¹ïŒ

åäœãããã«ã¯ãããã€ãã®ãã¡ã€ã«ãšãã£ã¬ã¯ããªãäœæããå¿
èŠããããŸãã
kernel.c | Cã§èšè¿°ãããããã°ã©ã ã³ãŒããããã°ã©ã ã¯ç»é¢ã«ã¡ãã»ãŒãžãåºåããŸãã |
ã¡ã€ã¯ãã¡ã€ã« | Makefileãããã°ã©ã ã®ã¢ã»ã³ããªå
šäœãå®è¡ããããŒãã€ã¡ãŒãžãäœæããã¹ã¯ãªããã |
ãªã³ã«ãŒ.ld | ã«ãŒãã«ã®ãªã³ã«ãŒã¹ã¯ãªããã |
loader.s | Grubã«ãã£ãŠåŒã³åºãããCããã°ã©ã ããã¡ã€ã³é¢æ°ã«å¶åŸ¡ã転éããã¢ã»ã³ãã©ãŒã³ãŒãã |
å«ã/ | ããããŒãã¡ã€ã«ã®ãããã©ã«ããŒã |
ã°ã©ã/ | GRUBãã¡ã€ã«ãã©ã«ããŒã |
å
±é/ | æ±çšæ©èœãåãããã©ã«ããŒã printfã®å®è£
ãå«ã¿ãŸãã |
ã¹ããã1.ã¿ãŒã²ããããã°ã©ã ïŒã«ãŒãã«ïŒã®ã³ãŒãã®äœæïŒ
ç»é¢ã«ã¡ãã»ãŒãžãåºåããæ¬¡ã®ã³ãŒããå«ãkernel.cãã¡ã€ã«ãäœæããŸãã
#include "printf.h" #include "screen.h" #include "types.h" void main(void) { clear_screen(); printf("\n>>> Hello World!\n"); }
ããã§ã¯ãã¹ãŠãããªãã¿ã§ã·ã³ãã«ã§ãã printfããã³clear_screen颿°ã®è¿œå ã«ã€ããŠã¯ãåŸã§èª¬æããŸãã ãããŸã§ã®éãGrubã§ããŒãã§ããããã«ããã®ã³ãŒããå¿
èŠãªãã®ã§è£å®ããå¿
èŠããããŸãã
ã«ãŒãã«ããã«ãããŒã圢åŒã«ããã«ã¯ãã«ãŒãã«ã€ã¡ãŒãžã®æåã®8ãããã€ãã«æ¬¡ã®æ§é ãå¿
èŠã§ãã
0x1BADB002 =ããžã㯠| ãã«ãããŒã眲å |
0x0 =ãã©ã° | ã«ãŒãã«ãšããŒããŒïŒã«ãŒãã«ïŒã«æž¡ããããã©ã¡ãŒã¿ãŒãããŒãããããã®è¿œå èŠä»¶ãå«ããã©ã°ã ãã®å Žåããã¹ãŠã®ãã©ã°ããªã»ãããããŸãã |
0xE4524FFE =-ïŒããžãã¯+ãã©ã°ïŒ | ãã§ãã¯ãµã ã |
ããããã¹ãŠã®æ¡ä»¶ãæºããããŠããå ŽåãGrubã¯ïŒ
eaxããã³ïŒ
ebxãééãããããããã«ãããŒãæ
å ±æ§é ããã³å€0x1BADB002ãžã®ãã€ã³ã¿ãŒãç»é²ããŸãã ãã«ãããŒãæ
å ±æ§é ã«ã¯ãããŒããããã¢ãžã¥ãŒã«ãšãã®å Žæã®ãªã¹ããå«ãããŸããŸãªæ
å ±ãå«ãŸããŠããŸãããããã®æ
å ±ã¯ãã·ã¹ãã ãããã«ããŒãããããã«å¿
èŠã«ãªãå ŽåããããŸãã
ããã°ã©ã ãã¡ã€ã«ã«å¿
èŠãªçœ²åãå«ããã«ã¯ã次ã®å
容ã®loader.sãã¡ã€ã«ãäœæããŸãã
.text .global loader # making entry point visible to linker # setting up the Multiboot header - see GRUB docs for details .set FLAGS, 0x0 # this is the Multiboot 'flag' field .set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header .set CHECKSUM, -(MAGIC + FLAGS) # checksum required .align 4 .long MAGIC .long FLAGS .long CHECKSUM # reserve initial kernel stack space .set STACKSIZE, 0x4000 # that is, 16k. .lcomm stack, STACKSIZE # reserve 16k stack .comm mbd, 4 # we will use this in kmain .comm magic, 4 # we will use this in kmain loader: movl $(stack + STACKSIZE), %esp # set up the stack movl %eax, magic # Multiboot magic number movl %ebx, mbd # Multiboot data structure call main # call C code cli hang: hlt # halt machine should kernel return jmp hang
ã³ãŒããããè©³çŽ°ã«æ€èšããŠãã ããã ãã®ã³ãŒãã¯
wiki.osdev.org/Bare_Bonesããã»ãšãã©
倿ŽãããŠã
ãŸãã ã gccã¯ã³ã³ãã€ã«ã«äœ¿çšããããããGASæ§æã䜿çšãããŸãã ãã®ã³ãŒãã®æ©èœã詳ããèŠãŠã¿ãŸãããã
.text
åŸç¶ã®ã³ãŒãã¯ãã¹ãŠãå®è¡å¯èœã»ã¯ã·ã§ã³.textã«åé¡ãããŸãã
.global loader
ãªã³ã«ããèŠããããŒããŒã·ã³ãã«ã宣èšããŸãã ããã¯ããªã³ã«ãŒãããŒããŒããšã³ããªãã€ã³ããšããŠäœ¿çšããããã«å¿
èŠã§ãã
.set FLAGS, 0x0 # FLAGS = 0x0 .set MAGIC, 0x1BADB002 # MAGIC = 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) # CHECKSUM = -(MAGIC + FLAGS) .align 4 # 4 .long MAGIC # MAGIC .long FLAGS # FLAGS .long CHECKSUM # CHECKSUM
ãã®ã³ãŒãã¯ããã«ãããŒã圢åŒã®çœ²åã圢æããŸãã .setãã£ã¬ã¯ãã£ãã¯ãæåã®å€ãã³ã³ãã®å³åŽã®åŒã«èšå®ããŸãã .align 4ãã£ã¬ã¯ãã£ãã¯ãåŸç¶ã®ã³ã³ãã³ãã4ãã€ãã«æããŸãã .longãã£ã¬ã¯ãã£ãã¯ã次ã®4ãã€ãã«å€ãæ ŒçŽããŸãã
.set STACKSIZE, 0x4000 # STACKSIZE = 0x4000 .lcomm stack, STACKSIZE # STACKSIZE . stack .comm mbd, 4 # 4 mdb COMMON .comm magic, 4 # 4 magic COMMON
ããŒãããã»ã¹äžãgrubã¯ã¹ã¿ãã¯ãæ§æããŸãããã«ãŒãã«ãæåã«è¡ãã¹ãããšã¯ãã¹ã¿ãã¯ãæ§æããããšã§ãããã®ããã«ã0x4000ïŒ16KbïŒãã€ããäºçŽããŸãã .lcommãã£ã¬ã¯ãã£ãã¯ã.bssã»ã¯ã·ã§ã³ã§ãå°æ°ç¹ã®åŸã«æå®ããããã€ãæ°ãäºçŽããŸãã ååã¹ã¿ãã¯ã¯ãã³ã³ãã€ã«ããããã¡ã€ã«ã§ã®ã¿è¡šç€ºãããŸãã .commãã£ã¬ã¯ãã£ãã¯.lcommãšåãã§ãããã·ã³ãã«åã¯ã°ããŒãã«ã«å®£èšãããŸãã ããã¯ãCã³ãŒãã§æ¬¡ã®è¡ãèšè¿°ããããšã§äœ¿çšã§ããããšãæå³ããŸãã
extern int magic
ãããŠä»ãæåŸã®éšåïŒ
loader: movl $(stack + STACKSIZE), %esp # movl %eax, magic # %eax magic movl %ebx, mbd # %ebx mbd call main # main cli # hang: hlt # jmp hang # hang
æåã®åœä»€ã¯ãã¹ã¿ãã¯ã®ãããã®å€ãïŒ
espã¬ãžã¹ã¿ã«ä¿åããŸãã ã¹ã¿ãã¯ã倧ãããªããšãã¹ã¿ãã¯ã«å²ãåœãŠãããç¯å²ã®çµããã®ã¢ãã¬ã¹ãïŒ
espã«æžã蟌ãŸããŸãã åŸç¶ã®2ã€ã®åœä»€ã¯ãGrubãïŒ
eaxãïŒ
ebxã¬ãžã¹ã¿ã«æž¡ãå€ã4ãã€ãã®ä»¥åã«äºçŽãããç¯å²ã«ä¿åããŸãã æ¬¡ã«ããã§ã«Cã§èšè¿°ãããŠããã¡ã€ã³é¢æ°ãåŒã³åºãããŸãã ãã®æé ããæ»ããšãããã»ããµã¯ã«ãŒãããŸãã
ã¹ããã2.ããã°ã©ã ïŒã·ã¹ãã ã©ã€ãã©ãªïŒã®è¿œå ã³ãŒãã®æºåïŒ
ããã°ã©ã å
šäœããŒãããäœæããããããprintf颿°ã¯ãŒãããäœæããå¿
èŠããããŸãã ãããè¡ãã«ã¯ãããã€ãã®ãã¡ã€ã«ãæºåããŸãã
å
±éããã³ã€ã³ã¯ã«ãŒããã©ã«ããŒãäœæããŸãã
mkdir common mkdir include
äžè¬çãªprintf颿°ã®å®è£
ãå«ããã¡ã€ã«common \ printf.cãäœæããŸãã ãã®ãã¡ã€ã«å
šäœã¯ã
www.bitvisor.orgãããžã§ã¯ãããååŸã§ããŸãã bitvisorã®ãœãŒã¹å
ã®ãã¡ã€ã«ãžã®ãã¹ïŒcore / printf.cã ã¿ãŒã²ããããã°ã©ã ã§äœ¿çšããããã«ãbitvisorããã³ããŒãããprintf.cãã¡ã€ã«ã§ã次ã®è¡ã眮ãæããå¿
èŠããããŸãã
#include "initfunc.h" #include "printf.h" #include "putchar.h" #include "spinlock.h"
è¡ããšïŒ
#include "types.h" #include "stdarg.h" #include "screen.h"
次ã«ããã®ãã¡ã€ã«ããprintf_init_global颿°ãšãã®ãã¹ãŠã®åç
§ãåé€ããŸãã
static void printf_init_global (void) { spinlock_init (&printf_lock); } INITFUNC ("global0", printf_init_global);
次ã«ããã®ãã¡ã€ã«å
ã®printf_lock倿°ãšãã®ãã¹ãŠã®åç
§ãåé€ããŸãã
static spinlock_t printf_lock; ⊠spinlock_lock (&printf_lock); ⊠spinlock_unlock (&printf_lock);
printf颿°ã¯putchar颿°ã䜿çšããŸããããããèšè¿°ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ã次ã®å
容ã®ãã¡ã€ã«common \ screen.cãäœæããŸãã
#include "types.h" #define GREEN 0x2 #define MAX_COL 80
æå®ãããã³ãŒãã«ã¯ãããã¹ãã¢ãŒãã§ç»é¢ã«æåãå°å·ããããã®ç°¡åãªããžãã¯ãå«ãŸããŠããŸãã ãã®ã¢ãŒãã§ã¯ã2ãã€ãã䜿çšããŠæåïŒ1ã€ã¯æåã³ãŒãããã1ã€ã¯ãã®å±æ§ïŒãæžã蟌ã¿ãç»é¢ã«ããã«è¡šç€ºãããã¢ãã¬ã¹0xB8000ã§å§ãŸããããªã¡ã¢ãªã«çŽæ¥æžã蟌ã¿ãŸãã ç»é¢è§£å床ã¯80x25æåã§ãã æåã¯ãPUTãã¯ãã䜿çšããŠçŽæ¥å°å·ãããŸãã
ããã€ãã®ããããŒãã¡ã€ã«ã®ã¿ãæ¬ èœããŠããŸãã
1.ãã¡ã€ã«ã«ã¯\ screen.hãå«ãŸããŸãã printf颿°ã§äœ¿çšãããputchar颿°ã宣èšããŸãã ãã¡ã€ã«ã®å
容ïŒ
#ifndef _SCREEN_H #define _SCREEN_H void clear_screen( void ); void putchar( int c ); #endif
2.ãã¡ã€ã«ã«ã¯\ printf.hãå«ãŸããŸãã mainã§äœ¿çšãããprintf颿°ã宣èšããŸãã ãã¡ã€ã«ã®å
容ïŒ
#ifndef _PRINTF_H #define _PRINTF_H int printf (const char *format, ...); #endif
3.ãã¡ã€ã«ã«ã¯\ stdarg.hãå«ãŸããŸãã äºåã«æ°ãããããªãåŒæ°ãå埩åŠçãã颿°ã宣èšããŸãã ãã¡ã€ã«å
šäœã¯
www.bitvisor.orgãããžã§ã¯ãããååŸãããŸãã bitvisorãããžã§ã¯ãã³ãŒãå
ã®ãã¡ã€ã«ãžã®ãã¹ïŒinclude \ core \ stdarg.hã
4.ãã¡ã€ã«ã«ã¯\ types.hãå«ãŸããŸãã NULLããã³size_tã宣èšããŸãã ãã¡ã€ã«ã®å
容ïŒ
#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #endif
ãããã£ãŠãã€ã³ã¯ã«ãŒããã©ã«ããŒãšå
±éãã©ã«ããŒã«ã¯ãããã°ã©ã ã«å¿
èŠãªæå°éã®ã·ã¹ãã ã©ã€ãã©ãªã³ãŒããå«ãŸããŠããŸãã
ã¹ããã3.ãªã³ã«ãŒçšã®ã¹ã¯ãªããã®äœæïŒ
ãªã³ã«ãã¿ãŒã²ããããã°ã©ã ãã¡ã€ã«ïŒkernel.binïŒãçæããããã«äœ¿çšãããlinker.ldãã¡ã€ã«ãäœæããŸãã ãã¡ã€ã«ã«ã¯æ¬¡ã®ãã®ãå«ãŸããŠããå¿
èŠããããŸãã
ENTRY (loader) LMA = 0x00100000; SECTIONS { . = LMA; .multiboot ALIGN (0x1000) : { loader.o( .text ) } .text ALIGN (0x1000) : { *(.text) } .rodata ALIGN (0x1000) : { *(.rodata*) } .data ALIGN (0x1000) : { *(.data) } .bss : { *(COMMON) *(.bss) } /DISCARD/ : { *(.comment) } }
çµã¿èŸŒã¿é¢æ°ENTRYïŒïŒã䜿çšãããšãã«ãŒãã«ã®ãšã³ããªãã€ã³ããèšå®ã§ããŸãã ã«ãŒãã«ã®èµ·ååŸã«grubãå¶åŸ¡ãæž¡ãã®ã¯ãã®ã¢ãã¬ã¹ã§ãã ãã®ã¹ã¯ãªããã䜿çšããŠããªã³ã«ãŒã¯ELF圢åŒã®ãã€ããªãã¡ã€ã«ãäœæããŸãã ELFãã¡ã€ã«ã¯ãäžé£ã®ã»ã°ã¡ã³ããšã»ã¯ã·ã§ã³ã§æ§æãããŠããŸãã ã»ã°ã¡ã³ãã®ãªã¹ãã¯ãããã°ã©ã ããããŒããŒãã«ãã»ã¯ã·ã§ã³ããããŒããŒãã«ã®ã»ã¯ã·ã§ã³ã®ãªã¹ãã«å«ãŸããŠããŸãã ãªã³ã«ã¯ã»ã¯ã·ã§ã³ãã€ã¡ãŒãžããŒããŒïŒãã®å Žåã¯GRUBïŒãã»ã°ã¡ã³ãã䜿çšããŠåäœããŸãã

å³ãããããããã«ãã»ã°ã¡ã³ãã¯ã»ã¯ã·ã§ã³ã§æ§æãããŠããŸãã ã»ã¯ã·ã§ã³ãèšè¿°ãããã£ãŒã«ãã®1ã€ã¯ãã»ã¯ã·ã§ã³ãå®è¡æã«ååšããä»®æ³ã¢ãã¬ã¹ã§ãã å®éãã»ã°ã¡ã³ãã«ã¯ããã®å Žæãèšè¿°ãã2ã€ã®ãã£ãŒã«ãããããŸããã»ã°ã¡ã³ãã®ä»®æ³ã¢ãã¬ã¹ãšã»ã°ã¡ã³ãã®ç©çã¢ãã¬ã¹ã§ãã ã»ã°ã¡ã³ãã®ä»®æ³ã¢ãã¬ã¹ã¯ãã³ãŒãå®è¡æã®ã»ã°ã¡ã³ãã®æåã®ãã€ãã®ä»®æ³ã¢ãã¬ã¹ã§ããã»ã°ã¡ã³ãã®ç©çã¢ãã¬ã¹ã¯ãã»ã°ã¡ã³ããããŒãããç©çã¢ãã¬ã¹ã§ãã ã¢ããªã±ãŒã·ã§ã³ã®å Žåããããã®ã¢ãã¬ã¹ã¯åžžã«äžèŽããŸãã Grubã¯ãç©çã¢ãã¬ã¹ã§ã€ã¡ãŒãžã»ã°ã¡ã³ããããŠã³ããŒãããŸãã Grubã¯ããŒãžã®ã¢ãã¬ã¹æå®ãæ§æããªããããããã°ã©ã ã§ã¯ä»®æ³ã¡ã¢ãªãæ§æãããŠããªããããã»ã°ã¡ã³ãã®ä»®æ³ã¢ãã¬ã¹ã¯ç©çã¢ãã¬ã¹ãšäžèŽããå¿
èŠããããŸãã
SECTIONS
ã»ã¯ã·ã§ã³ã«ã€ããŠããã«èª¬æããŸãã
. = LMA;
ãã®åŒã¯ãåŸç¶ã®ãã¹ãŠã®ã»ã¯ã·ã§ã³ãLMAã¢ãã¬ã¹ã®åŸã«ããããšããªã³ã«ãŒã«ç€ºããŸãã
ALIGN (0x1000)
äžèšã®ãã£ã¬ã¯ãã£ãã¯ãã»ã¯ã·ã§ã³ã0x1000ãã€ãã«æããããããšãæå³ããŸãã
.multiboot ALIGN (0x1000) : { loader.o( .text ) }
loader.oãã¡ã€ã«ã®.textã»ã¯ã·ã§ã³ãå«ãå¥ã®ãã«ãããŒãã»ã¯ã·ã§ã³ã¯ããã«ãããŒã圢åŒã®çœ²åãã«ãŒãã«ã€ã¡ãŒãžã®æåã®8kbã«å
¥ãããã«ããããã«èšèšãããŠããŸãã
.bss : { *(COMMON) *(.bss) }
*ïŒCOMMONïŒã¯ãåœä»€.commããã³.lcommã«ãã£ãŠã¡ã¢ãªãäºçŽãããé åã§ãã .bssã»ã¯ã·ã§ã³ã«é
眮ããŸãã
/DISCARD/ : { *(.comment) }
DISCARDãšããŒã¯ããããã¹ãŠã®ã»ã¯ã·ã§ã³ãç»åããåé€ãããŸãã ãã®å Žåããªã³ã«ãŒã®ããŒãžã§ã³ã«é¢ããæ
å ±ãå«ã.commentã»ã¯ã·ã§ã³ãåé€ããŸãã
次ã®ã³ãã³ãã䜿çšããŠãã³ãŒãããã€ããªãã¡ã€ã«ã«ã³ã³ãã€ã«ããŸãã
as -o loader.o loader.s gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o kernel.o -c kernel.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o printf.o -c common/printf.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o screen.o -c common/screen.c ld -T linker.ld -o kernel.bin kernel.o screen.o printf.o loader.o
objdumpã䜿çšããŠããªã³ã¯åŸã®ã«ãŒãã«ã€ã¡ãŒãžãã©ã®ããã«ãªãããèŠãŠãããŸãã
objdump -ph ./kernel.bin

ã芧ã®ãšãããã€ã¡ãŒãžå
ã®ã»ã¯ã·ã§ã³ã¯ããªã³ã«ã¹ã¯ãªããã§èª¬æããã»ã¯ã·ã§ã³ãšäžèŽããŠããŸãã ãªã³ã«ãŒã¯ã説æãããã»ã¯ã·ã§ã³ãã3ã€ã®ã»ã°ã¡ã³ãã圢æããŸããã æåã®ã»ã°ã¡ã³ãã«ã¯ãã»ã¯ã·ã§ã³.multibootã.textã.rodataãå«ãŸããä»®æ³ããã³ç©çã¢ãã¬ã¹0x00100000ããããŸãã 2çªç®ã®ã»ã°ã¡ã³ãã«ã¯ã.dataã»ã¯ã·ã§ã³ãš.bssã»ã¯ã·ã§ã³ãå«ãŸãã0x00104000ã«ãããŸãã ããã§ãGrubã䜿çšããŠãã®ãã¡ã€ã«ãããŠã³ããŒãããæºåããã¹ãŠæŽããŸããã
ã¹ããã4. GrubããŒãããŒããŒã®æºåïŒ
grubãã©ã«ããŒãäœæããŸãã
mkdir grub
ã€ã¡ãŒãžã«ã€ã³ã¹ããŒã«ããããã«å¿
èŠãªããã€ãã®Grubãã¡ã€ã«ããã®ãã©ã«ããŒã«ã³ããŒããŸãïŒGrubãã·ã¹ãã ã«ã€ã³ã¹ããŒã«ãããŠããå Žåã以äžã®ãã¡ã€ã«ãååšããŸãïŒã ãããè¡ãã«ã¯ã次ã®ã³ãã³ããå®è¡ããŸãã
cp /usr/lib/grub/i386-pc/stage1 ./grub/ cp /usr/lib/grub/i386-pc/stage2 ./grub/ cp /usr/lib/grub/i386-pc/fat_stage1_5 ./grub/
次ã®å
容ã§grub / menu.lstãã¡ã€ã«ãäœæããŸãã
timeout 3 default 0 title mini_os root (hd0,0) kernel /kernel.bin
æé 5.ããŒãã€ã¡ãŒãžãèªååããŠäœæããŸãã
ãã«ãããã»ã¹ãèªååããã«ã¯ãmakeãŠãŒãã£ãªãã£ã䜿çšããŸãã ãããè¡ãã«ã¯ãã³ã³ãã€ã«ããŠãœãŒã¹ã³ãŒããã³ã³ãã€ã«ããã«ãŒãã«ãã³ã³ãã€ã«ããããŒãã€ã¡ãŒãžãäœæããã¡ã€ã¯ãã¡ã€ã«ãäœæããŸãã ã¡ã€ã¯ãã¡ã€ã«ã«ã¯æ¬¡ã®å
容ãå«ãŸããŠããå¿
èŠããããŸãã
CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = \ loader.o \ common/printf.o \ common/screen.o \ kernel.o image: @echo "Creating hdd.img..." @dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1 @echo "Creating bootable first FAT32 partition..." @losetup /dev/loop1 ./hdd.img @(echo c; echo u; echo n; echo p; echo 1; echo ; echo ; echo a; echo 1; echo t; echo c; echo w;) | fdisk /dev/loop1 1>/dev/null 2>&1 || true @echo "Mounting partition to /dev/loop2..." @losetup /dev/loop2 ./hdd.img \ --offset `echo \`fdisk -lu /dev/loop1 | sed -n 10p | awk '{print $$3}'\`*512 | bc` \ --sizelimit `echo \`fdisk -lu /dev/loop1 | sed -n 10p | awk '{print $$4}'\`*512 | bc` @losetup -d /dev/loop1 @echo "Format partition..." @mkdosfs /dev/loop2 @echo "Copy kernel and grub files on partition..." @mkdir -p tempdir @mount /dev/loop2 tempdir @mkdir tempdir/boot @cp -r grub tempdir/boot/ @cp kernel.bin tempdir/ @sleep 1 @umount /dev/loop2 @rm -r tempdir @losetup -d /dev/loop2 @echo "Installing GRUB..." @echo "device (hd0) hdd.img \n \ root (hd0,0) \n \ setup (hd0) \n \ quit\n" | grub --batch 1>/dev/null @echo "Done!" all: kernel.bin rebuild: clean all .so: as -o $@ $< .co: $(CC) -Iinclude $(CFLAGS) -o $@ -c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o $@ $^ clean: rm -f $(OBJFILES) hdd.img kernel.bin
ãã¡ã€ã«ã§ã¯ã2ã€ã®äž»ãªç®æšã宣èšãããŠããŸããall-ã«ãŒãã«ãã³ã³ãã€ã«ããimage-ããŒããã£ã¹ã¯ãäœæããŸãã éåžžã®ã¡ã€ã¯ãã¡ã€ã«ãšåæ§ã«ããã¹ãŠã®ã¿ãŒã²ããã«ã¯ã* .sããã³* .cãã¡ã€ã«ããªããžã§ã¯ããã¡ã€ã«ïŒ* .oïŒã«ã³ã³ãã€ã«ãã.soããã³.coã®ãµããŽãŒã«ãšã以åã«äœæãããã¹ã¯ãªããã§ãªã³ã«ãŒãåŒã³åºãkernel.binãçæããããã®ã¿ãŒã²ãããå«ãŸããŸãã ãããã®ç®æšã¯ãã¹ããã3ã«ãªã¹ããããŠããã³ãã³ããšãŸã£ããåãã³ãã³ããå®è¡ããŸãã
ããã§æãè峿·±ãã®ã¯ãããŒãã€ã¡ãŒãžhdd.imgïŒã¿ãŒã²ããã€ã¡ãŒãžïŒã®äœæã§ãã ãããã©ã®ããã«èµ·ããããæ®µéçã«èããŠã¿ãŸãããã
dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1
ãã®ã³ãã³ãã¯ãããã«äœæ¥ãè¡ãããã€ã¡ãŒãžãäœæããŸãã ã»ã¯ã¿ãŒã®æ°ã¯å¶ç¶éžæãããŸããã§ããïŒ16065 = 255 *63ãããã©ã«ãã§ã¯ãfdsikã¯ãã£ã¹ã¯ã§CHSãžãªã¡ããªãæã£ãŠãããã®ããã«åäœããŸããããããŒïŒHïŒ= 255ãã»ã¯ã¿ãŒïŒSïŒ= 63ãã·ãªã³ããŒïŒCïŒã¯ãã£ã¹ã¯ãµã€ãºã ãããã£ãŠãfdsikãŠãŒãã£ãªãã£ãããã©ã«ãã®ãžãªã¡ããªã倿Žããã«äœ¿çšã§ããæå°ãã£ã¹ã¯ãµã€ãºã¯ã512 * 255 * 63 * 1 = 8225280ãã€ãã§ãã512ã¯ã»ã¯ã¿ãŒãµã€ãºã§ã1ã¯ã·ãªã³ããŒæ°ã§ãã
次ã«ãããŒãã£ã·ã§ã³ããŒãã«ãäœæãããŸãã
losetup /dev/loop1 ./hdd.img (echo c; echo u; echo n; echo p; echo 1; echo ; echo ; echo a; echo 1; echo t; echo c; echo w;) | fdisk /dev/loop1 1>/dev/null 2>&1 || true
æåã®ã³ãã³ãã¯ãhdd.imgãã¡ã€ã«ããããã¯ããã€ã¹/ dev / loop1ã«ããŠã³ããããã¡ã€ã«ãããã€ã¹ãšããŠæäœã§ããããã«ããŸãã 2çªç®ã®ã³ãã³ãã¯ãããã€ã¹/ dev / loop1ã«ããŒãã£ã·ã§ã³ããŒãã«ãäœæããŸãããã®ããŒãã«ã«ã¯ããã£ã¹ã¯ã®ãã©ã€ããªããŒãããŒãã£ã·ã§ã³ã1ã€ããããã£ã¹ã¯å
šäœãå æããFAT32ãã¡ã€ã«ã·ã¹ãã ã©ãã«ãä»ããŠããŸãã
次ã«ãäœæããã»ã¯ã·ã§ã³ããã©ãŒãããããŸãã ãããè¡ãã«ã¯ããããã¯ããã€ã¹ãšããŠããŠã³ããããã©ãŒããããå®è¡ããŸãã
losetup /dev/loop2 ./hdd.img \ --offset `echo \`fdisk -lu /dev/loop1 | sed -n 10p | awk '{print $$3}'\`*512 | bc` \ --sizelimit `echo \`fdisk -lu /dev/loop1 | sed -n 10p | awk '{print $$4}'\`*512 | bc` losetup -d /dev/loop1
æåã®ã³ãã³ãã¯ã以åã«äœæãããããŒãã£ã·ã§ã³ãããã€ã¹/ dev / loop2ã«ããŠã³ãããŸãã -offsetãªãã·ã§ã³ã¯ã»ã¯ã·ã§ã³ã®å
é ã®ã¢ãã¬ã¹ãæå®ãã-sizelimitã¯ã»ã¯ã·ã§ã³ã®æ«å°Ÿã®ã¢ãã¬ã¹ãæå®ããŸãã äž¡æ¹ã®ãã©ã¡ãŒã¿ãŒã¯ãfdiskã³ãã³ãã䜿çšããŠååŸãããŸãã
mkdosfs /dev/loop2
mkdosfsãŠãŒãã£ãªãã£ã¯ãããŒãã£ã·ã§ã³ãFAT32ãã¡ã€ã«ã·ã¹ãã ã«ãã©ãŒãããããŸãã
ã«ãŒãã«ãçŽæ¥çµã¿ç«ãŠãããã«ã以åã«èª¬æããã³ãã³ããå€å
žçãªmakefileæ§æã§äœ¿çšãããŸãã
次ã«ãããŒãã£ã·ã§ã³ã«GRUBãã€ã³ã¹ããŒã«ããæ¹æ³ãæ€èšããŸãã
mkdir -p tempdir # mount /dev/loop2 tempdir # mkdir tempdir/boot # /boot cp -r grub tempdir/boot/ # grub /boot cp kernel.bin tempdir/ # sleep 1 # Ubuntu umount /dev/loop2 # rm -r tempdir # losetup -d /dev/loop2 #
äžèšã®ã³ãã³ããå®è¡ãããšãã€ã¡ãŒãžã¯GRUBãã€ã³ã¹ããŒã«ããæºåãæŽããŸãã æ¬¡ã®ã³ãã³ãã¯ãhdd.imgãã£ã¹ã¯ã€ã¡ãŒãžã®MBRã«GRUBãã€ã³ã¹ããŒã«ããŸãã
echo "device (hd0) hdd.img \n \ root (hd0,0) \n \ setup (hd0) \n \ quit\n" | grub --batch 1>/dev/null
ãã¹ãŠããã¹ãããæºåãã§ããŸããïŒ
ã¹ããã6.èµ·åïŒ
ã³ã³ãã€ã«ããã«ã¯ã次ã®ã³ãã³ãã䜿çšããŸãã
make all
ãã®åŸãkernel.binãã¡ã€ã«ã衚瀺ãããŸãã
ããŒããã£ã¹ã¯ã€ã¡ãŒãžãäœæããã«ã¯ã次ã®ã³ãã³ãã䜿çšããŸãã
sudo make image
ãã®çµæãhdd.imgãã¡ã€ã«ã衚瀺ãããŸãã
ããã§ãhdd.imgãã£ã¹ã¯ã€ã¡ãŒãžããèµ·åã§ããŸãã æ¬¡ã®ã³ãã³ãã§ããã確èªã§ããŸãã
qemu -hda hdd.img -m 32
ãŸãã¯ïŒ
qemu-system-i386 -hda hdd.img


å®éã®ãã·ã³ã§ç¢ºèªããã«ã¯ããã©ãã·ã¥ãã©ã€ãã§ãã®ã€ã¡ãŒãžãddã«ããŠãããããèµ·åããå¿
èŠããããŸãã ããšãã°ã次ã®ã³ãã³ãã§ã¯ïŒ
sudo dd if=./hdd.img of=/dev/sdb
èŠçŽãããšãå®è¡ãããã¢ã¯ã·ã§ã³ã®çµæãšããŠãã·ã¹ãã ããã°ã©ãã³ã°ã®åéã§ããŸããŸãªå®éšãè¡ãããšãã§ãããœãŒã¹ãšã¹ã¯ãªããã®ã»ãããååŸã§ãããšèšããŸãã æåã®ã¹ãããã¯ããã€ããŒãã€ã¶ãŒããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªã©ã®ã·ã¹ãã ãœãããŠã§ã¢ã®äœæã«åããŠè¡ãããŸããã
ã·ãªãŒãºã®æ¬¡ã®èšäºãžã®ãªã³ã¯ïŒ
"
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒ ããŒã2 "
ã
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒ ããŒã3ïŒã°ã©ãã£ãã¯ã¹ ã
ã
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒ ããŒã4.䞊åèšç® ã
ã
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒ ããŒã5. OSããBIOSã«ã¢ã¯ã»ã¹ãã ã
ã
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒ ããŒã6. FATãã¡ã€ã«ã·ã¹ãã ã§ãã£ã¹ã¯ãæäœããããã®ãµããŒã ã