èªã¿åã/æžã蟌ã¿ã»ã¯ã¿ãŒã®ã¬ãã«ã§ãã£ã¹ã¯ãæäœãã
æåã«ããã£ã¹ã¯ã®æäœæ¹æ³ãåŠã³ãŸãã
ãããã£ãŠãBIOSå²ã蟌ã¿ãçºçããå¯èœæ§ããããŸãã BIOSã¯ä»ã®æ©èœã®äžã§ãç¹ã«ããã£ã¹ã¯ãæäœããããã®ã€ã³ã¿ãŒãã§ã€ã¹ãã€ãŸãå²ã蟌ã¿int 0x13ãæäŸããŸãã å²ã蟌ã¿ã«ãã£ãŠæäŸããããµãŒãã¹ã®ãªã¹ãã¯ã Wikipediaã«ãããŸãã ãã£ã¹ã¯ã®èªã¿æžããµãŒãã¹ã«èå³ããããŸãã
BIOSãåäœãããã£ã¹ã¯äžã®ã»ã¯ã¿ãŒãã¢ãã¬ã¹æå®ããã«ã¯ãCHSïŒ ã·ãªã³ããŒãããã»ã¯ã¿ãŒ ïŒãšLBAïŒ è«çãããã¯ã¢ãã¬ã¹æå® ïŒã®2ã€ã®æ¹æ³ããããŸãã CHSã¢ãã¬ã¹æå®ã¯ããã£ã¹ã¯ãžãªã¡ããªã®äœ¿çšã«åºã¥ããŠãããã»ã¯ã¿ãŒã¢ãã¬ã¹ã¯ãã·ãªã³ããŒãããããã»ã¯ã¿ãŒã®3ã€ã®åº§æšã®çµã¿åããã§ãã ãã®æ¹æ³ã§ã¯ãæ倧8GBãã¢ãã¬ã¹æå®ã§ããŸãã å²ã蟌ã¿int0x13ã¯ããã®ã¢ãã¬ã¹æå®ã䜿çšããŠãã£ã¹ã¯ã®èªã¿åãããã³æžã蟌ã¿ãè¡ãæ©èœãæäŸããŸãã
8GBã¯éåžžã«å°ããããã®ã¢ãã¬ã¹æå®æ¹æ³ã¯æ代é ãã§ããããã¹ãŠã®ææ°ã®ïŒããã§ã¯ãªãïŒããŒããã£ã¹ã¯ã³ã³ãããŒã©ãŒãLBAã¢ãã¬ã¹æå®ããµããŒãããŠããããšã¯æããã§ãã LBAã¢ãã¬ãã·ã³ã°ã¯ããã£ã¹ã¯ãžãªã¡ããªããæœè±¡åããåã»ã¯ã¿ãŒã«åå¥ã®çªå·ãå²ãåœãŠãŸãã ã»ã¯ã¿ãŒçªå·ã¯ãŒãããå§ãŸããŸãã LBAã¯48ãããã䜿çšããŠãããã¯çªå·ãæå®ããŸããããã«ããã512ãã€ãã®ã»ã¯ã¿ãŒãµã€ãºãèæ ®ããŠã128 PiBã®ã¢ãã¬ã¹æå®ãå¯èœã«ãªããŸãã å²ã蟌ã¿int0x13ã¯ãLBAã䜿çšããŠãã£ã¹ã¯ã«ã»ã¯ã¿ãŒãèªã¿æžãããããã®2ã€ã®ãµãŒãã¹ãæäŸããŸãã ãããã䜿çšããŸãã ã»ã¯ã¿ãŒãèªã¿åãããã«ãin0x13å²ã蟌ã¿ã¯æ¬¡ã®ãã©ã¡ãŒã¿ãŒãæ³å®ããŠããŸãã
DAPæ§é ïŒ
å²ã蟌ã¿ã¯æ¬¡ã®å€ãè¿ããŸãã
ãã©ã¡ãŒã¿ãŒã®1ã€ã¯ãã£ã¹ã¯çªå·ã§ãã äœããã®æ¹æ³ã§äœæ¥ãããã£ã¹ã¯çªå·ã調ã¹ãå¿ èŠããããŸãã çªå·ä»ãã¯æ¬¡ã®ãšããã§ãïŒãããããŒãã£ã¹ã¯ïŒfddïŒãããã³ãããããŒãšããŠãšãã¥ã¬ãŒãããããã¹ãŠã®ãã®ã¯æåããçªå·ãä»ããããããŒããã£ã¹ã¯ïŒhddïŒãããã³ãããã®ããã«ãšãã¥ã¬ãŒãããããã¹ãŠã®ãã®ïŒããšãã°ãusbãã©ãã·ã¥ãã©ã€ãïŒã¯0x80ããçªå·ä»ããããŸãã ãã®æ°å€ã¯ãBIOSèšå®ã®ããŒãã·ãŒã±ã³ã¹ãšã¯é¢ä¿ãããŸããã ãã®å Žåãäœæ¥ãããã£ã¹ã¯ã¯ããŒãå ã®ãã£ã¹ã¯ã§ãã
BIOSãMBRå¶åŸ¡ã転éãããšããã¢ãã¬ã¹0000hïŒ7C00hã«ããŒãããDLã¬ãžã¹ã¿ã§å¿ èŠãªããŒãããã€ã¹çªå·ã転éããŸãã ããã¯ãBIOSãšMBRã®éã®ã€ã³ã¿ãŒãã§ã€ã¹ã®äžéšã§ãã ãããã£ãŠããã®çªå·ã¯GRUBã«åé¡ãããããã§ãã£ã¹ã¯ã§ã®äœæ¥ã«äœ¿çšãããŸãã 次ã«ãGRUBã¯ãã®OSçªå·ããã«ãããŒãæ å ±æ§é ã®äžéšãšããŠæž¡ããŸãã
GRUBããOSã«å¶åŸ¡ã移ããçŽåŸããã®æ§é äœãžã®ãã€ã³ã¿ãŒã¯EBXã¬ãžã¹ã¿ãŒã«ãããŸãã æ§é ã®æåã®ãã£ãŒã«ãã¯ãã©ã°ã§ããã2çªç®ã®ããããèšå®ãããŠããå Žåãboot_deviceãã£ãŒã«ãã¯æ£ããã§ãã ãã®ãã£ãŒã«ãã¯ãã«ãããŒãæ å ±æ§é ã«ãå±ãããã®äžäœãã€ãïŒãã£ãŒã«ããµã€ãºã¯4ãã€ãïŒã«å¿ èŠãªãã£ã¹ã¯çªå·ãæ ŒçŽãããinter0x13å²ã蟌ã¿ãèªèãããŸãã ãããã£ãŠãGRUBã䜿çšããŠãã»ã¯ã¿ãŒããã£ã¹ã¯ã«èªã¿æžãããããã®ãã©ã¡ãŒã¿ãŒãæ¬ èœããŠããŸãã
ã»ã¯ã¿ãŒã®ãã£ã¹ã¯ãžã®èªã¿æžããåŠã³ãŸãããããã¯ç¢ºãã«éèŠã§ãã ãããããã¡ã€ã«ã·ã¹ãã ã¯ãã£ã¹ã¯å šäœã«é¢é£ä»ããããŠããã®ã§ã¯ãªãããã®äžéšãã€ãŸãããŒãã£ã·ã§ã³ã«ã®ã¿é¢é£ä»ããããŠããŸãã ãã¡ã€ã«ã·ã¹ãã ãæäœããã«ã¯ããã¡ã€ã«ã·ã¹ãã ãé 眮ãããŠããã»ã¯ã·ã§ã³ãå§ãŸãã»ã¯ã¿ãŒãèŠã€ããå¿ èŠããããŸãã ãã£ã¹ã¯ã§äœ¿çšå¯èœãªã»ã¯ã¿ãŒã«é¢ããæ å ±ã¯ãMBRãšåãå Žæã®ãã£ã¹ã¯ã®æåã®ã»ã¯ã¿ãŒã«ä¿åãããŸãã ããŸããŸãªMBR圢åŒããããŸããã次ã®æ§é ã¯ããããã¹ãŠã«åœãŠã¯ãŸããŸãã
ããŒãã£ã·ã§ã³æ å ±ã¯ããŒãã£ã·ã§ã³ããŒãã«ã«ä¿åãããŸãã èµ·åã§ãããã£ã¹ã¯ã«ã¯ããã©ã€ããªããŒãã£ã·ã§ã³ã4ã€ãããããŸããã ã»ã¯ã·ã§ã³ãšã³ããªããšã«8ãã€ãããããŸãã æåã®ãã€ãã¯ãã©ã°ã§ããå€ã0x80ã®å ŽåãããŒãã£ã·ã§ã³ã¯èµ·åå¯èœã§ãã äœæ¥äžã®MBRã³ãŒãã¯ãããŒãããŒãã£ã·ã§ã³ãæ¢ããŠããã4ã€ã®ã»ã¯ã·ã§ã³ãå®è¡ããŸãã çºèŠåŸãMBRã¯ãã®ã»ã¯ã·ã§ã³ã®æåã®ã»ã¯ã¿ãŒã®å 容ãã¢ãã¬ã¹0000hïŒ7C00hã«ã³ããŒããããã§å¶åŸ¡ã移ããŸãã ããŒãããŒãã£ã·ã§ã³ã®æåã®ã»ã¯ã¿ãŒã®LBAã¢ãã¬ã¹ã«èå³ããããŸããããã¯ãã«ãŒãã«ãé 眮ãããŠããå Žæã§ãããèªã¿èŸŒããã¡ã€ã«ã·ã¹ãã ãããããã§ãã ãã®ã¢ãã¬ã¹ãååŸããã«ã¯ããã£ã¹ã¯ã®æåã®ã»ã¯ã¿ãŒãèªã¿åãããã®ããŒãã£ã·ã§ã³ããŒãã«ãèŠã€ããããŒãã£ã·ã§ã³ããŒãã«ã§ããŒãããŒãã£ã·ã§ã³ãèŠã€ãããã®ã¬ã³ãŒãããç®çã®ãã£ãŒã«ããèªã¿åãå¿ èŠããããŸãã
ãããã£ãŠããã£ã¹ã¯ããã»ã¯ã¿ãŒãèªã¿åãããã£ã¹ã¯äžã®å¿ èŠãªããŒãã£ã·ã§ã³ã®å Žæãç¥ãããã®ã¡ã«ããºã ããããŸãã ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã¡ã€ã«ã·ã¹ãã ã®æäœæ¹æ³ãåŠç¿ããŸãã
ãã¡ã€ã«ã·ã¹ãã ãæäœãã
ãã¡ã€ã«ã·ã¹ãã ãæäœããã«ã¯ã fat_io_libã©ã€ãã©ãªã䜿çšããŸãã ã©ã€ãã©ãªã¯GPLã©ã€ã»ã³ã¹ã®äžã§å©çšå¯èœã§ãã libcã§å©çšå¯èœãªãã®ãšåæ§ã«ããã¡ã€ã«ãšãã£ã¬ã¯ããªãæäœããããã®ã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããŸãã fopenïŒïŒãfgetsïŒïŒãfputcïŒïŒãfreadïŒïŒãfwriteïŒïŒãªã©ã®é¢æ°ãå®è£ ãããŠããŸãã ãã®äœæ¥ã®ããã®ã©ã€ãã©ãªãŒã«ã¯ãã»ã¯ã¿ãŒã®æžã蟌ã¿ãšã»ã¯ã¿ãŒã®èªã¿åããšãã2ã€ã®æ©èœã®ã¿ãå¿ èŠã§ããæåã®æ©èœã¯ãªãã·ã§ã³ã§ãã é¢æ°ã«ã¯æ¬¡ã®ãããã¿ã€ãããããŸãã
int media_read(uint32 sector, uint8 *buffer, uint32 sector_count); int media_write(uint32 sector, uint8 *buffer, uint32 sector_count); Return: int, 1 = success, 0 = failure.
ã©ã€ãã©ãªã¯çŽç²ãªCã§æžãããŠããŸãããããããŸã奜æçã§ãã ããOSã§äœ¿çšããå Žåããã®äžã®1è¡ãå€æŽããå¿ èŠã¯ãããŸããã ã©ã€ãã©ãªã¯ãã»ã¯ã¿ãŒããã¡ã€ã«ã·ã¹ãã ããŒãã£ã·ã§ã³ã®äžéšãšããŠèªã¿åãããšãæ³å®ããŠããŸãã
ãã®ãããããŒãã£ã·ã§ã³ã«ã»ã¯ã¿ãŒãèªã¿æžãããããã®é¢æ°ãããããããã®é¢æ°ã䜿çšããFAT16 / 32ãæäœããããã®ã©ã€ãã©ãªããããŸãã ãã¹ãŠããŸãšããŠãçµæãå®èšŒããããšãæ®ã£ãŠããŸãã ããããã³ãŒãã«ç§»ãåã«ãç§ãã¡ã䜿çšããããšããŠããã¢ãããŒããå®éã«éåžžã«é©çšå¯èœã§ããããšã瀺ããããšæããŸãã 以äžã¯ã VBRãŠã£ã³ããŠ7ã®ããäžéšã§ãint0x13å²ã蟌ã¿ã«ãã£ãŠãã£ã¹ã¯ã»ã¯ã¿ãŒãèªã¿åãããŸãã ãã®ã³ãŒãã¯ãããŒãã¢ãã¡ãŒã·ã§ã³ãã¬ã³ããªã³ã°ããç¬éãŸã§ãã·ã¹ãã ã®ããŒãããã»ã¹äžã«ç¹°ãè¿ãåŒã³åºãããŸãã
ãã®ã³ãŒããåŒã³åºãããã«ãWindows 7ã¯ããã®æ¹æ³ãšåæ§ã«ãä¿è·ã¢ãŒããããªã¢ã«ã¢ãŒãã«ããŸãã¯ãã®éã«ç§»è¡ããŸãã ããã¯ãQEMUã§Windows 7ãå®è¡ããããšã§ç°¡åã«ç¢ºèªã§ããŸãã QEMUã¯ããããã¬ãŒã®æ¥ç¶ãåŸ æ©ããå¿ èŠããããŸãã ãããã¬ãŒïŒgdbïŒãæ¥ç¶ããåŸãã¢ãã¬ã¹ïŒ0x7c00 + 0x11dïŒã«ãã¬ãŒã¯ãã€ã³ããèšå®ããŸãã ãã¬ãŒã¯ãã€ã³ãã®ããªã¬ãŒã¯ããã®é¢æ°ã®åŒã³åºããæå³ããŸãã ã¡ãªã¿ã«ãWindows XPã§ã¯ãã®ã¡ã«ããºã ã¯ååšãããBIOSå²ã蟌ã¿ãçºçãããããã«ãããã§VM86ã¢ãŒãã«åãæ¿ããŸãã
ïŒ éèŠïŒ äžé£ã®èšäºã®ç¬¬5éšããã®ãã¹ãŠã®ã¹ããããæ£åžžã«ééããåŸã«ã®ã¿ããã以éã®ãã¹ãŠã®ã¢ã¯ã·ã§ã³ãæ£åžžã«å®è¡ã§ããŸãã
æé 1. kernel.cã®ã¡ã€ã³ããžãã¯ãå€æŽãã
1. kernel.cãã¡ã€ã«ã«æ¬¡ã®å®£èšãè¿œå ããŸãã
#include "multiboot.h" #include "fat_io_lib/fat_filelib.h" // loader.s extern u32 mbd; extern u32 magic;
RAMã®ãµã€ãºãå°å·ããã³ãŒã
u64 ram_size = GetRamsize(); printf("ram_size = %llu(%lluMb)\n", ram_size, ram_size / 0x100000);
次ã®ã³ãŒãã«çœ®ãæããŸãã
// , grub- if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printf("Invalid magic number: 0x%x\n", magic); return; } multiboot_info_t *p_multiboot_info = (multiboot_info_t*)mbd; // Is boot_device valid? if ((p_multiboot_info->flags & 2) == 0) { printf("Error: boot_device(2) flag is clear\n"); return; } // if (InitBootMedia(p_multiboot_info->boot_device >> 24) == 0) { printf("Error: InitBootMedia failed.\n"); return; } // fat_io_lib fl_init(); if (fl_attach_media(ReadBootMedia, WriteBootMedia) != FAT_INIT_OK) { printf("Error: Media attach failed.\n"); return; } // /boot/grub fl_listdirectory("/boot/grub"); // /boot/grub/menu.lst char str[64]; void *file = fl_fopen("/boot/grub/menu.lst", "r"); if (file == 0) { printf("Error: can not open file.\n"); return; } printf("\nConntent of the file /boot/grub/menu.lst:\n"); while (fl_fgets(str, sizeof(str), file)) { printf("%s", str); }
mbdããã³ããžãã¯å€æ°ã®ã¡ã¢ãªã¯loader.sãã¡ã€ã«ã§äºçŽãããŠãããããCã³ãŒãã®ã°ããŒãã«å€æ°ãšåæ§ã«äœ¿çšã§ããŸããããžãã¯å€æ°ã«ã¯ããã«ãããŒãæšæºãããŒãã«äœ¿çšãããããšã確èªãã眲åãå«ãŸããŠããŸãã mbdå€æ°ã¯ãmultiboot.hã§å®£èšãããŠããmultiboot_info_tæ§é äœãæããŸãã ããŒããã£ã¹ã¯çªå·ã¯ã次ã®åŒã§æ±ºå®ãããŸã-p_multiboot_info-> boot_device >>24ãInitBootMediaé¢æ°ã¯ããã£ã¹ã¯çªå·ãèšæ¶ãããã¡ã€ã«ã·ã¹ãã ã®æåã®ã»ã¯ã¿ãŒãæ€çŽ¢ããŸããããã«ããããã¹ãŠã®ãªãã»ãããèªã¿åãããšãã§ããŸãã
åæåã®ããã®fat_io_libã©ã€ãã©ãªã§ã¯ãfl_initãšfl_attach_mediaã®2ã€ã®é¢æ°ãåŒã³åºãå¿ èŠããããŸãã æåã®é¢æ°ã¯ã©ã€ãã©ãªã®å éšæ§é ããªã»ãããã2çªç®ã®é¢æ°ã¯ãã©ã¡ãŒã¿ãŒãšããŠãã£ã¹ã¯ãžã®ã»ã¯ã¿ãŒã®èªã¿åããšæžã蟌ã¿ã®æ©èœãåãåãããã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ã«äœ¿çšãããŸãã 次ã¯ãã©ã€ãã©ãªã®æäœã®ãã¢ã§ãã/boot / grubãã©ã«ããŒå ã®ãã¡ã€ã«ã®ãªã¹ãã衚瀺ãããmenu.lstãã¡ã€ã«ã®å 容ãå°å·ãããŸãã
2. multiboot.hãã¡ã€ã«ãincludeãã©ã«ããŒã«è¿œå ããŸãã ãã¡ã€ã«ã®å 容㯠ã以åã®ããŒãžã§ã³ã®ä»æ§ãµã€ãããååŸããŸãã
ã¹ããã2.ãã£ã¹ã¯ãæäœããæ©èœãè¿œå ãã
1. include \ callrealmode.hãã¡ã€ã«ã§ã次ã®é¢æ°ã®ãããã¿ã€ããè¿œå ããŸãã
u32 InitBootMedia(u8 bootDevice); int ReadBootMedia(unsigned long sector, unsigned char *buffer, unsigned long sectorCount); int WriteBootMedia(unsigned long sector, unsigned char *buffer, unsigned long sectorCount);
2. include \ callrealmode_asm.hãã¡ã€ã«ã§ã次ã®ããšãè¡ãããããã«ãenum callrealmode_Funcã«æ°ããå€ãè¿œå ããŸãã
enum callrealmode_Func { CALLREALMODE_FUNC_GETSYSMEMMAP = 0, CALLREALMODE_FUNC_READ_DISK = 1 }; , : <source lang="c"> struct callrealmode_read_disk { u64 start_sector_lba; u32 buff_addr; u32 sectors_count; u16 disk_number; u8 ret_code; } __attribute__ ((packed));
callrealmode_Dataæ§é å ã®å ±çšäœã«ã宣èšãããã°ããã®callrealmode_read_diskæ§é ãè¿œå ããŸãã 以äžãååŸããå¿ èŠããããŸãã
struct callrealmode_Data { enum callrealmode_Func func : 16; union { struct callrealmode_GetSysMemMap getsysmemmap; struct callrealmode_read_disk readdisk; }; } __attribute__ ((packed));
3. fat_io_libã©ã€ãã©ãªã§äœ¿çšãããstrncmpããã³strncpyé¢æ°ãinclude \ string.hãã¡ã€ã«ã«è¿œå ããŸãã
static inline int strncmp ( const char * str1, const char * str2, unsigned int num ) { for ( ; num > 0; str1++, str2++, --num) { if (*str1 != *str2) return ((*(unsigned char *)str1 < *(unsigned char *)str2) ? -1 : +1); else if (*str1 == '\0') return 0; } return 0; } static inline char* strncpy ( char * dst, const char * src, unsigned int num ) { if (num != 0) { char *d = dst; const char *s = src; do { if ((*d++ = *s++) == 0) { while (--num) *d++ = 0; break; } } while (--num); } return dst; }
4.次ã®å®£èšãcallrealmode.cãã¡ã€ã«ã«è¿œå ããŸãã
#include "fat_io_lib/fat_opts.h" #include "mbr.h" u64 g_BootPartitionStart = 0; // u32 g_BootDeviceInt13Num = 0; //
ãããŠããã€ãã®æ©èœïŒ
// int ReadBootMedia(unsigned long sector, unsigned char *buffer, unsigned long sectorCount) { struct callrealmode_Data param; // , // RM, param.func = CALLREALMODE_FUNC_READ_DISK; // int13. // // 1Mb, "buffer" . // "low_mem_buff", // RM , CALLREALMODE_OFFSET < 1Mb int i; void *low_mem_buff = CALLREALMODE_OFFSET + (&callrealmode_end - &callrealmode_start); for (i = 0; i < sectorCount; i++) { param.readdisk.start_sector_lba = sector + g_BootPartitionStart + i; param.readdisk.buff_addr = (u32)low_mem_buff; param.readdisk.disk_number = g_BootDeviceInt13Num; param.readdisk.sectors_count = 1; callrealmode_Call(¶m); // int 0x13 "param" if (param.readdisk.ret_code) { return 0; // error } memcpy(buffer + i * FAT_SECTOR_SIZE, low_mem_buff, FAT_SECTOR_SIZE); } return 1; // success } // . int WriteBootMedia(unsigned long sector, unsigned char *buffer, unsigned long sectorCount) { return 0; // error } // u32 InitBootMedia(u8 bootDevice) { g_BootDeviceInt13Num = bootDevice; // MBRSector_t mbr; if (ReadBootMedia(0, (u8*)&mbr, 1) == 0) { return 0; } // if (mbr.mbr_sign[0] != 0x55 || mbr.mbr_sign[1] != 0xaa) { return 0; } // int i; for (i = 0; i < 4; i++) { if (mbr.part[i].boot_indicator == 0x80) break; } if (i == 4) { return 0; } // g_BootPartitionStart = mbr.part[i].start_lva; printf("start sector = %lld boot dev int13 num = 0x%x\n", g_BootPartitionStart, g_BootDeviceInt13Num); return 1; }
ReadBootMediaããã³WriteBootMediaé¢æ°ã¯ãfat_io_libã©ã€ãã©ãªãã»ã¯ã¿ãŒã®èªã¿åã/æžã蟌ã¿ã«äœ¿çšããŸãã ãã®äŸã§ã¯ãã£ã¹ã¯ãžã®æžã蟌ã¿ããªããããWriteBootMediaé¢æ°ã¯ãªãã·ã§ã³ã§ãããã¹ã¿ãã§ãã ãã®å®è£ ã¯ãReadBootMediaé¢æ°ã«äŒŒãŠããŸãã ReadBootMediaé¢æ°ã¯ãåã®èšäºã®param.funcåãŸã§ã®GetRamsizeé¢æ°ã«äŒŒãŠãããparam.getsysmemmapã®ä»£ããã«param.readdiskã䜿çšãããŸãã InitBootMediaé¢æ°ã¯ãg_BootPartitionStartãšg_BootDeviceInt13Numã®å€ãåæåãããããä»ã®2ã€ã®åã«åŒã³åºãå¿ èŠããããŸãã
5. callrealmode_asm.sãå€æŽããŸãã é¢æ°ãšåŒã°ããå¥ã®ã¿ã€ãã®CALLREALMODE_FUNC_READ_DISKãè¿œå ãããšã次ã®ãã®ãåŸãããŸãã
# enum callrealmode_Func CALLREALMODE_FUNC_GETSYSMEMMAP = 0x0 CALLREALMODE_FUNC_READ_DISK = 0x1
次ã«ãé¢æ°ã®ã¿ã€ããšãã£ã¹ã¯ããçŽæ¥èªã¿åã£ãã³ãŒãã«ãã1ã€ãã§ãã¯ãè¿œå ããŸãã 以äžãååŸããå¿ èŠããããŸãã
callrealmode_switch: OFF_FUNC = 44 # %bp # func callrealmode_Data # Which function? movw OFF_FUNC(%bp),%ax cmp $CALLREALMODE_FUNC_GETSYSMEMMAP,%ax je getsysmemmap cmp $CALLREALMODE_FUNC_READ_DISK,%ax je readdisk ret readdisk: OFF_START_SECTOR = 50 # start_sector_lba callrealmode_Data OFF_BUFFER_ADDR = 58 # buff_addr callrealmode_Data OFF_SECTORS_COUNT = 62 # sectors_count callrealmode_Data OFF_DISK_NUMBER = 66 # disk_number callrealmode_Data OFF_RETURN_CODE = 68 # ret_code callrealmode_Data push %bp mov %sp,%bp # DAP pushl OFF_START_SECTOR+4(%bp) pushl OFF_START_SECTOR+0(%bp) pushl OFF_BUFFER_ADDR(%bp) pushw OFF_SECTORS_COUNT(%bp) pushw $0x10 mov %sp,%si # ds:si , .. DAP mov OFF_DISK_NUMBER(%bp),%dl # dl mov $0x42,%ah # EXTENDED READ int $0x13 # CALL DISK BIOS mov %ah,OFF_RETURN_CODE(%bp) # add $0x10,%sp # DAP pop %bp ret
readdiskã©ãã«ã¯ãcallrealmode_Dataæ§é ããDAPæ§é ã圢æããint0x13ãåŒã³åºãã³ãŒããæããŸãã ã³ãŒãã§ã¯ãã©ãã«callrealmode_switchã®åŸã«ãreaddiskãåŒã³åºãå¿ èŠããããã©ããã確èªããããã®2ã€ã®åœä»€ãè¿œå ãããŸããã
6. MBRãæäœããããã®å®çŸ©ãå«ãinclude \ mbr.hãã¡ã€ã«ãè¿œå ããŸãã ãã®å 容ïŒ
#ifndef _MBR_H_ #define _MBR_H_ #include "types.h" struct MBRPartitionEntry { unsigned char boot_indicator; unsigned char start_head; unsigned short start_sector : 6; unsigned short start_cylinder : 10; unsigned char sys_id; unsigned char end_head; unsigned short end_sector : 6; unsigned short end_cylinder : 10; unsigned int start_lva; unsigned int size_in_sectors; } __attribute__ ((packed)); typedef struct MBRPartitionEntry MBRPartitionEntry_t; struct MBRSector { u8 code[446]; MBRPartitionEntry_t part[4]; u8 mbr_sign[2]; } __attribute__ ((packed)); typedef struct MBRSector MBRSector_t;
MBRSectoræ§é äœã¯ãInitBootMediaé¢æ°ã§äœ¿çšãããŸãã
ã¹ããã3. fat_io_libã©ã€ãã©ãªãŒãè¿œå ããŠå®è¡ãã
1. fat_io_lib.zipã¢ãŒã«ã€ããããŠã³ããŒããããããžã§ã¯ãã«ãŒãã®fat_io_libãã©ã«ããŒã«è§£åããŸãã
2.空ã®ãã¡ã€ã«assert.hããã³stdlib.hãincludeãã©ã«ããŒã«è¿œå ããŸãã ã©ã€ãã©ãªãã³ã³ãã€ã«ããããã«å¿ èŠã§ãã
3. Makefileãä¿®æ£ããŸãã ã©ã€ãã©ãªã®ãã¡ã€ã«ãã³ã³ãã€ã«ã®ç®æšã®ãªã¹ãã«è¿œå ããŸãã 以äžãååŸããå¿ èŠããããŸãã
FAT_LIB_OBJFILES = \ ./fat_io_lib/fat_access.o \ ./fat_io_lib/fat_cache.o \ ./fat_io_lib/fat_filelib.o \ ./fat_io_lib/fat_format.o \ ./fat_io_lib/fat_misc.o \ ./fat_io_lib/fat_string.o \ ./fat_io_lib/fat_table.o \ ./fat_io_lib/fat_write.o OBJFILES = \ loader.o \ common/printf.o \ common/screen.o \ common/string.o \ kernel.o \ callrealmode.o \ callrealmode_asm.o \ descriptor.o \ $(FAT_LIB_OBJFILES)
è¡ã眮ãæãã
@dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1
ã«
@dd if=/dev/zero of=./hdd.img bs=1M count=10 1>/dev/null 2>&1
çŸåšãç»åãµã€ãºã¯10Mbã§ãã ããã¯ãmkdosfsã³ãã³ããããŒãã£ã·ã§ã³ãFAT12ã§ã¯ãªãFAT16ã«ãã©ãŒãããããããã«ããããã§ãã FAT12ã¯ãfat_io_libã©ã€ãã©ãªã§ã¯ãµããŒããããŠããŸããã
è¡ã眮ãæãã
$(CC) -Iinclude $(CFLAGS) -o $@ -c $<
ã«
$(CC) -Iinclude -DFAT_PRINTF_NOINC_STDIO $(CFLAGS) -o $@ -c $<
ãã®å®çŸ©ã§ã¯ãã©ã€ãã©ãªã«ã¯stdio.hãå«ãŸããŸããããprintfé¢æ°ã®æ¢è£œã®ãããã¿ã€ãã䜿çšããŸããããã¯ãç§ãã¡ã®ãã®ãšåãã§ãæ¢ã«å®è£ ãããŠããŸãã
4.ãããžã§ã¯ãããªãã«ãããŸã
make rebuild
sudo make image
5.å®è¡
sudo qemu-system-i386 -hda hdd.img
以äžãååŸããå¿ èŠããããŸãã
åã®éšåãšåæ§ã«ãUSBãã©ãã·ã¥ãã©ã€ãã§ddã®hdd.imgã€ã¡ãŒãžãäœæããããããèµ·åããããšã§å®éã®ããŒããŠã§ã¢ã®ã³ãŒãã確èªã§ããŸãã
ãã®çµæãFAT16ããã³FAT32ãã¡ã€ã«ã·ã¹ãã ã§ã®äœæ¥ãå®è£ ããŸããã æ¢è£œã®ã©ã€ãã©ãªã䜿çšããŠå°ãããŸãããŸããããFATããã€ã¹ãç解ããããšã¯ããã»ã©é¢çœããªãã1ã€ã®èšäºã«åãŸãå¯èœæ§ã¯äœãã§ãããã ããªãããããèªãã®ãé¢çœããšæã£ãŠãã ããã æé ãå®è¡ããéã«åé¡ãããå Žåã¯ãã³ã¡ã³ããæžããŠãã ããïŒ
åã®éšåãžã®ãªã³ã¯ã®éžæïŒ
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒããŒã2
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒããŒã3ïŒã°ã©ãã£ãã¯ã¹
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒããŒã4.䞊åèšç®
- ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªãã§ããã°ã©ã ãå®è¡ããæ¹æ³ïŒããŒã5. OSããBIOSã«ã¢ã¯ã»ã¹ãã