【转载】How to develop your own Boot Loader【怎么样开发自己的bootloader】

How to develop your own Boot Loader

怎么样开发自己的bootloader

Table of content【目录】

1. Who may be interested【谁可能会感兴趣】
2. What is Boot Loader 【Bootloader是什么】
3. Be ready to go deeper 【深入探究前的准备】
3.1. So what language you should know to develop Boot Loader 【开发Bootloader需要掌握哪些语言】
3.2. What compiler you need 【需要哪些编译器】
3.3. How system boots 【系统如何启动】
4. Let’s code 【代码实现】
4.1 Program architecture 【编程架构】
4.2 Development environment 【开发环境】
4.3 BIOS interrupts and screen clearing 【BIOS的中断和清屏】
4.4 «Mixed code» 【混合编程】
4.5 CString implementation 【类CString实现】
4.6 CDisplay implementation 【类CDisplay实现】
4.7 Types.h implementation 【Types.h实现】

4.8 BootMain.cpp implementation 【BootMain.cpp实现】
4.9 StartPoint.asm implementation 【StartPoint.asm实现】
5. Let’s assemble everything 【让我来组装它们】
5.1 Creation of COM file 【COM文件的创建】
5.2 Assembly automation 【自动组合】
6. Testing and Demonstration 【测试和示范】
6.1 How to test boot loader. 【怎么测试bootloader】
6.2 Testing with the virtual machine VmWare 【使用VmWare进行测试】
6.2.1 Creation of the virtual machine 【创建虚拟机】
6.2.2 Working with Disk Explorer for NTFS 【NTFS资源管理器运行】
6.3 Testing on the real hardware 【在真实机器上测试】
6.4 Debug 【调试】
7. Information Sources 【拓展】
8. Conclusion 【总结】

Who may be interested【谁可能会感兴趣】

Most of all I’ve written this article for those who have been always interested in the way the different things work. It is for those developers who usually create their applications in high-level languages such as C, C++ or Java, but faced with the necessity to develop something at low-level. We will consider low-level programming on the example of working at system loading.

我写这篇文章的主要面向那些对于不同事物能一起运转持浓厚兴趣的人。是那些程序员,经常使用高级语言例如 C, C++或者Java来开发应用,但又得做底层开发。我们将会系统加载启动为例来说下底层编程。

 

We will describe what is going after you turn on a computer; how the system is loading. As the practical example we will consider how you can develop your own boot loader which is actually the first point of the system booting process.

我们将会描述当你开启电脑之后都会发生什么,系统是如何启动的。作为一个实例,我们将会教你怎么样开发你自己的bootloader,它是系统启动处理的第一步。

 

What is Boot Loader【Bootloader是什么】

Boot loader is a program situated at the first sector of the hard drive; and it is the sector where the boot starts from. BIOS automatically reads all content of the first sector to the memory just after the power is turned on, and jump to it. The first sector is also called Master Boot Record. Actually it is not obligatory for the first sector of the hard drive to boot something. This name has been formed historically because developers used to boot their operating systems with such mechanism.

Boot loader是位于磁盘第一扇区的一段程序,它是boot开始执行的扇区。在机器上电后,BIOS自动读取存储器上第一扇区的所有内容,并跳转过去。第一扇区也叫作主动引导程序(Master Boot Record,MBR)。事实上磁盘上第一扇区没有义务去启动系统。这个名字由来已久,因为程序员使用这样的机制去启动他们的系统。

 

Be ready to go deeper【深入探究前的准备】

In this section I will tell about knowledge and tools you need to develop your own boot loader and also remind some useful information about system boot.

本节会告诉你要开发自己的bootloader需要哪些知识和工具,也会讲解关于系统启动的一些有用信息。

So what language you should know to develop Boot Loader【开发Bootloader需要掌握哪些语言】

On the first stage on the computer work the control of hardware is performed mainly by means of BIOS functions known as interrupts. The implementation of interrupts is given only in Assembler – so it is great if you know it at least a little bit. But it’s not the necessary condition. Why? We will use the technology of “mixed code” where it is possible to combine high-level constructions with low-level commands. It makes our task a little simpler.

在电脑工作的第一个阶段上对于硬件控制执行主要是被称为中断的BIOS功能。中断的实现主要是通过汇编语言——所以你要是懂一些汇编会很好。但是这并不是必要条件。为什么呢?我们将会使用混合编程,以链接上层架构和底层命令。这会使我们的任务能更简单些。

 

In this article the main development languages is C++. But if you have brilliant knowledge of C then it will be easy to learn required C++ elements. In general even the C knowledge will be enough but then you will have to modify the source code of the examples that I will descried here.

在这篇文章中主要的开发语言是C++。但是如果你精通C语言的话,将会很容易的学到这里所需的C++元素。一般来说C语言已经足够了,甚至你不得不修改在接下来要讲解的示例源码的情况下。

 

If you know Java or C# well unfortunately it won’t help for our task. The matter is that the code of Java and C# languages that is produced after compilation is intermediate. The special virtual machine is used to process it (Java Machine for Java, and .NET for C#) which transform intermediate code into processor instructions. After that transformation it can be executed. Such architecture makes it impossible to use mixed code technology – and we are going to use it to make our life easier, so Java and C# don’t work here.

如果你只懂Java或C#,不幸的是这对我们的任务没有任何帮助。Java和c#语言的代码编译后产生的中间体。需要特定的虚拟机来处理它(Java Machine和.NET),虚拟机用于把中间体转换成处理器指令。转化后指令可以执行。这样的架构使混合编程称为可能——我们可以使用这些让我们的编程容易些,因此Java和C#在这里不适用。

 

So to develop the simple boot loader you need to know C or C++ and also it would be good if you know something about Assembler – language into which all high-level code is transformed it the end.

因此开发简单的bootloader需要你懂得C或者C++,如果你懂些汇编语言(高级语言最终都要转化为汇编语言)将会更好。

What compiler you need【需要哪些编译器】

To use mixed code technology you need at least two compilers: for Assembler and C/C++, and also the linker to join object files (.obj) into the one executable.

使用混合编程需要你至少懂得两种编译器,汇编语言和C/C++编译器,和把对象文件链接为可执行文件的链接器。

 

Now let’s talk about some special moments. There are two modes of processor functioning: real mode and protected mode. Real mode is 16-bit and has some limitations. Protected mode is 32-bit and is fully used in OS work. When it starts processor works in 16-bit mode. So to build the program and obtain executable file you will need the compiler and linker of Assembler for 16-bit mode. For C/C++ you will need only the compiler that can create object files for 16-bit mode.

现在让我们来讲下一些主要的知识点。处理器功能有两种模式:真实模式和保护模式。真实模式是16位的并且带有一些局限性。保护模式是32位的,可被操作系统充分利用。处理器开始运行时处于16位模式。因此为构建程序和生成可执行文件需要16位模式下的编译器和汇编链接器。使用C/C++,你只需要编译器,它可以创建16位模式的目标文件。

 

The modern compilers are made for 32-bit applications only so we won’t able to use them.

现在编译器只面向于32位程序,因为我们不能够使用它。

 

I tried a number of free and commercial compilers for 16-bit mode and choose Microsoft product. Compiler along with the linker for Assembler, C, C++ are included into the Microsoft Visual Studio 1.52 package and also can be downloaded from the official site of the company. Some details about compilers we need are given below.

我尝试了很多的免费和商业的16位编译器,最终选择了Microsoft的产品。Microsoft Visual Studio 1.52软件包集成了汇编语言,C/C++的编译器和链接器,可以从官方网点下载。编译器的一些细节如下:

 

ML 6.15 – Assembler compiler by Microsoft for 16-bit mode;

LINK 5.16 – the linker that can create .com files for 16-bit mode;

CL – С, С++ compiler for 16-bit mode.

You can also use some alternative variants:

DMC – free compile for Assembler, C, C++ for 16 and 32-bit mode by Digital Mars;

LINK – free linker for DMC compiler;

There are also some products by Borland:

BCC 3.5 – С, С++ compiler that can create files for 16-bit mode;

TASM - Assembler compiler for 16-bit mode;

TLINK – linker that can create .com files for 16-bit mode.

All code examples in this article were built with the Microsoft tools.

How system boots【系统如何启动】

In order to solve our task we should recall how the system is booting.

为了编辑磁盘,我们讲解下系统是怎么样启动的。

 

Let’s consider briefly how the system components are interacting when the system is booting (see Fig.1).

让我简单的看下当系统启动时系统组件是怎么样相互作用的(see Fig.1)。

 

fig1.PNG

Fig.1 – “How it boots”

After the control has been passed to the address 0000:7C00, Master Boot Record (MBR) starts its work and triggers the Operating System boot. You can learn more about MBR structure for example here.

跳转到控制地址0000:7C00后,MBR开始执行并触发操作系统启动。为了本实例,你可以多学些MBR的结构。

Let’s code【代码实现】

In the next sections we will be directly occupied with the low-level programming – we will develop our own boot loader.

在下一节,我们直接开始底层编程——开发我们自己的bootloader。

Program architecture【编程架构】

Boot loader that we are developing is for the training only. Its tasks are just the following:

我们要开发的bootloader只是为了练习。其目标如下:

 

1、Correct loading to the memory by 0000:7C00 address.【从地址0000:7C00处正确加载存储器】
2、Calling the BootMain function that is developed in the high-level language.【高级语言开发调用BootMain函数】
3、Show “”Hello, world…”, from low-level” message on the display.【在显示器上显示字符串 “”Hello, world…”, from low-level”

Program architecture is described on the Fig.2 that is followed by the text description.

编程架构描述如下。

 

fig2.PNG

Fig.2. – Program architecture description

The first entity is StartPoint that is developed purely in Assembler as far as high-level languages don’t have the necessary instructions. It tells compiler what memory model should be used, and what address the loading to the RAM should be performed by after the reading from the disk. It also corrects processor registers and passes control to the BootMain that is written in high-level language.

第一入口点是StartPoint,纯粹使用汇编语言开发,直到可以达到使用高级语言为止。它告诉编译器存储模块可以被使用,读取磁盘后获取可执行的RAM地址。纠正处理器的寄存器并把控制权传递给给使用高级语言开发的BootMain。

 

Next entity– BootMain – is an analogue of main that is in its turn the main function where all program functioning is concentrated.

第二个入口点——BootMain——和main函数类似,在main函数里可以把程序的功能链接起来。

 

CDisplay and CString classes take care of functional part of the program and show message on the screen. As you can see from the Fig.2 CDisplay class uses CStringclass in its work.

类CDisplay和CString作为程序的一部分主要是在屏幕上显示信息。通过图2可知类CDisplay调用了CString类。

Development environment【开发环境】

Here I use the standard development environment Microsoft Visual Studio 2005 or 2008. You can use any other tools but I made sure that these two with some settings made the compiling and work easy and handy.

这里我使用标准的开发环境Microsoft Visual Studio 2005 或者 2008。你也可以使用其他的工具,但是我认为这两个工具里的一些配置可以使编译简单和便利。

 

First we should create the project of Makefile Project type where the main work will be performed (see Fig.3).

第一步我们创建可执行main函数的Makefile Project工程。

 

File->New\Project->General\Makefile Project

fig3.PNG

Fig.3 – Create the project of Makefile type

BIOS interrupts and screen clearing【BIOS的中断和清屏】

To show our message on the screen we should clear it first. We will use special BIOS interrupt for this purpose.

在屏幕上显示我们的信息之前需要先清屏。我们使用特定的BIOS中断实现。

 

BIOS proposes a number of interrupts for the work with computer hardware such as video adapter, keyboard, disk system. Each interrupt has the following structure:

BIOS使用一系列的中断保证电脑的正常工作,例如:视频适配器,键盘,磁盘系统。每一个中断结构如下:

int [number_of_interrupt];

where number_of_interrupt is the number of interrupt 

number_of_interrupt 是中断号

 

Each interrupt has the certain number of parameters that should be set before calling it. The ah processor register is always responsible for the number of function for the current interrupt, and the other registers are usually used for the other parameters of the current operation. Let’s see how the work of int 10h interrupt is performed in Assembler. We will use the 00 function that changes the video mode and clears screen:

每一个中断在调用前都有一个唯一的序号与之对应。AH(cpu寄存器)存储当前中断的中断函数标号,其他的寄存器经常被用作存储当前操作的其他参数。我们来看下中断10h在汇编语言中的实现。

mov al, 02h ; setting  the graphical【图像】 mode 80x25(text)
mov ah, 00h ; code  of function of changing video mode
int 10h   ; call  interruption

We will consider only those interrupts and functions that will be used in our application. We will need:

我们只关心在程序中将要被用到的中断和函数。

  1. int10h, function 00h performs changing of video mode and clears screen;
  2. int10h, function 01h sets the cursor type;
  3. int10h, function 13h shows the string on the screen;
 

 

«Mixed code»【混合编程】

Compiler for C++ supports the inbuilt Assembler i.e. when writing code in Hig-level language you can use also low level language. Assembler Instructions that are used in the high level code are also called asm insertions. They consist of the key word __asm and the block of the Assembler instructions in braces:

C++编译器支持内嵌汇编,当编写高级语言代码时也可以使用底层语言。汇编指令被用在高级语言中称为内嵌汇编。使用关键字__asm和一对大括号标示汇编语言代码块。

__asm ;  key word that shows the beginning of the asm insertion
  { ;  block beginning

  … ; some asm code
  } ;  end of the block

To demonstrate mixed code let’s use the previously mentioned Assembler code that performed the screen clearing and combine it with C++ code.

为展示混合编程,我们使用上述的汇编代码来执行清屏操作,并嵌入到C++代码中。

void ClearScreen()
{
     __asm
    {
        mov al, 02h ; setting the graphical mode 80x25(text)
        mov ah, 00h ; code  of function of changing video mode
        int 10h   ; call interrupt
    }
}

CString implementation【类CString实现】

CString class is designed to work with strings. It includes Strlen() method that obtains pointer to the string as the parameter and returns the number of symbols in that string.

类CString主要作用于字符串。它包括Strlen()函数,以字符串指针作为参数,返回字符串长度。

 

  1. // CString.h
  2. #ifndef __CSTRING__
  3. #define __CSTRING__
  4. #include"Types.h" 
  5. classCString
  6. {
  7.    public:
  8.    static byte Strlen(constchar far* inStrSource );
  9. };
  10. #endif// __CSTRING__
  1. // CString.cpp
  2. #include"CString.h"
  3. byte CString::Strlen(constchar far* inStrSource )
  4. {
  5. byte lenghtOfString =0;
  6. while(*inStrSource++!='\0')
  7. {
  8. ++lenghtOfString;
  9. }
  10. return lenghtOfString;
  11. }

CDisplay implementation【类CDisplay实现】

CDisplay class is designed for the work with the screen. It includes several methods:

类CDisplay主要作用于屏幕。包括以下几个函数:

 

1) TextOut() – it prints the string on the screen. 【在屏幕上打印字符串】
2) ShowCursor() – it manages the cursor representation on the screen: show, hide.【控制屏幕上光标的显示、隐藏】
3) ClearScreen() – it changes the video mode and thus clears screen.【切换视频模式并清除屏幕】
  1. // CDisplay.h
  2. #ifndef __CDISPLAY__
  3. #define __CDISPLAY__
  4. //// colors for TextOut func
  5. #define BLACK 0x0
  6. #define BLUE 0x1
  7. #define GREEN 0x2
  8. #define CYAN 0x3
  9. #define RED 0x4
  10. #define MAGENTA 0x5
  11. #define BROWN 0x6
  12. #define GREY 0x7
  13. #define DARK_GREY 0x8
  14. #define LIGHT_BLUE 0x9
  15. #define LIGHT_GREEN 0xA
  16. #define LIGHT_CYAN 0xB
  17. #define LIGHT_RED 0xC
  18. #define LIGHT_MAGENTA 0xD
  19. #define LIGHT_BROWN 0xE
  20. #define WHITE 0xF
  21.  
  22. #include"Types.h"
  23. #include"CString.h"
  24.  
  25. classCDisplay
  26. {
  27. public:
  28. staticvoidClearScreen();
  29. staticvoidTextOut(
  30. constchar far* inStrSource,
  31. byte inX =0,
  32. byte inY =0,
  33. byte inBackgroundColor = BLACK,
  34. byte inTextColor = WHITE,
  35. bool inUpdateCursor =false
  36. );
  37. staticvoidShowCursor( bool inMode);
  38. };
  39. #endif// __CDISPLAY__
  40.  
  41.  
  42. // CDisplay.cpp
  43. #include"CDisplay.h"
  44.  
  45. voidCDisplay::TextOut(
  46. constchar far* inStrSource,
  47. byte inX,
  48. byte inY,
  49. byte inBackgroundColor,
  50. byte inTextColor,
  51. bool inUpdateCursor
  52. )
  53. {
  54. byte textAttribute =((inTextColor)|(inBackgroundColor <<4));
  55. byte lengthOfString =CString::Strlen(inStrSource);
  56. __asm
  57. {
  58. push bp
  59.       mov al, inUpdateCursor
  60. xor bh, bh
  61.       mov bl, textAttribute
  62. xor cx, cx
  63.      mov cl, lengthOfString
  64. mov dh, inY
  65. mov dl, inX
  66. mov es, word ptr[inStrSource +2]
  67. mov bp, word ptr[inStrSource]
  68. mov ah,13h
  69.       int10h
  70.       pop bp
  71. }
  72. }
  73.  
  74. voidCDisplay::ClearScreen()
  75. {
  76. __asm
  77. {
  78. mov al,02h
  79.       mov ah,00h
  80.       int10h
  81. }
  82. }
  83. voidCDisplay::ShowCursor( bool inMode)
  84. {
  85. byte flag = inMode ?0:0x32;
  86. __asm
  87. {
  88. mov ch, flag
  89. mov cl,0Ah
  90. mov ah,01hint10h
  91. }
  92. }
 
Types.h implementationTypes.h实现】

Types.h is the header file that includes definitions of the data types and macros.

Types.h是包含数据类型定义和宏的头文件。

 // Types.h
#ifndef __TYPES__
#define __TYPES__     
typedef unsigned char   byte;
typedef unsigned short  word;
typedef unsigned long   dword;
typedef char            bool;

#define true            0x1
#define false           0x0
#endif // __TYPES__

BootMain.cpp implementationBootMain.cpp实现】

BootMain() is the main function of the program that is the first entry point (analogue of main()). Main work is performed here.

BootMain()是程序的主函数,第一个入口点(类似于main()函数)。主要的工作在这里实现。

  1. // BootMain.cpp
  2. #include"CDisplay.h"
  3. #define HELLO_STR "\"Hello, world…\", from low-level..."
  4.  
  5. extern"C" 
  6.  
  7. voidBootMain()
  8. {
  9. CDisplay::ClearScreen();
  10. CDisplay::ShowCursor(false);
  11. CDisplay::TextOut(
  12. HELLO_STR,
  13. 0,
  14. 0,
  15. BLACK,
  16. WHITE,
  17. false
  18. );
  19. return;
  20. }
 
StartPoint.asm implementation【StartPoint.asm实现】
;------------------------------------------------------------
.286							   ; CPU type
;------------------------------------------------------------
.model TINY						   ; memory of model
;---------------------- EXTERNS -----------------------------
extrn				_BootMain:near	   ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------   
.code   
org				07c00h		   ; for BootSector
main:
				jmp short start	   ; go to main
				nop;----------------------- CODE SEGMENT -----------------------
start:	
        cli
        mov ax,cs               ; Setup segment registers
        mov ds,ax               ; Make DS correct
        mov es,ax               ; Make ES correct
        mov ss,ax               ; Make SS correct        
        mov bp,7c00h
        mov sp,7c00h            ; Setup a stack
        sti
                                ; start the program 
        call           _BootMain
        ret
        
        END main                ; End of program

Let’s assemble everything【让我来组装它们】

Creation of COM file【COM文件的创建】

Now when the code is developed we need to transform it to the file for the 16-bit OS. Such files are .com files. We can start each of compilers (for Assembler and C, C++) from the command line, transmit necessary parameters to them and obtain several object files as the result. Next we start linker to transform all .obj files to the one executable file with .com extension. It is working way but it’s not very easy.

现在代码我们写好了,需要把它转成16位操作系统文件。例如文件以.com结尾。我们可以通过命令行启动每一个编译器,传输必要的参数给它们,并输出一些目标文件。下一步,我们链接器把所有的.obj文件链接到一个可执行文件中。工作原理是这样的,但是却不简单。

 

Let’s automate the process. In order to do it we create .bat file and put commands with necessary parameters there. Fig.4 represents the full process of application assembling.

让我们来自动进行上述处理。我们创建.bat文件来实现它,并把命令和必要的参数写入其中。下图展示了处理的过程。

fig4.PNG
Fig.4 – Process of program compilation 
Build.bat

Let’s put compilers and linker to the project directory. In the same directory we create .bat file and fill it accordingly to the example (you can use any directory name instead of VC152 where compilers and linker are situated):

我们把编译器和链接器放到工程目录中。在该目录中创建.bat文件并根据实例需要填充它(你可以使用任何的目录名称代替VC152,这是编译器和链接器的存放目录)。

 

.\VC152\CL.EXE /AT /G2 /Gs /Gx /c /Zl *.cpp

.\VC152\ML.EXE /AT /c *.asm

.\VC152\LINK.EXE /T /NOD StartPoint.obj bootmain.obj cdisplay.obj cstring.obj

del *.obj

Assembly automation【自动组合】

As the final stage in this section we will describe the way how to turn Microsoft Visual Studio 2005, 2008 into the development environment with any compiler support. Go to the Project Properties: Project->Properties->Configuration Properties\General->Configuration Type.

作为本节的最后阶段,我们描述怎么配置Microsoft Visual Studio 2005, 2008包含所有编译器的开发环境。

 

Configuration Properties tab includes three items: GeneralDebuggingNMake. Go to NMake and set the path to the build.bat in the Build Command Line and Rebuild Command Line fields – Fig.5.
fig5.PNG
Fig.5 –NMake project settings 

If everything is correct then you can compile in the common way pressing F7 or Ctrl + F7. At that all attendant information will be shown in the Output window. The main advantage here is not only the assembly automation but also navigation thru the code errors if they happen.

如果配置好了,你可以直接使用F7 或 Ctrl + F7 来直接编译。所有的必要信息都会在输出窗口中打印出来。这里的主要优势是不仅装配自动化,而且在错误发生时,可以快速定位代码。

Testing and Demonstration【测试和示范】

This section will tell how to see the created boot loader in action, perform testing and debug.

这一节将会演示怎么创建bootloader,执行测试和调试。

How to test boot loader【怎么测试bootloader】

You can test boot loader on the real hardware or using specially designed for such purposes virtual machine – VmWare. Testing on the real hardware gives you more confidence that it works while testing on the virtual machine makes you confident that it just can work. Surely we can say that VmWare is great method for testing and debug. We will consider both methods.

你可以使用真实电脑测试bootloader或者使用VmWare来测试。在真实电脑上测试会给你更放心的感觉,相比在VmWare运行时,你只会认为程序只是可以工作。无疑我们会说使用VMWare测试和调试程序是一个很好的方法。这两种方式,我们都会考虑。

 

First of all we need a tool to write our boot loader to the virtual or physical disk. As far as I know there a number of free and commercial, console and GUI applications. I used Disk Explorer for NTFS 3.66 (version for FAT that is named Disk Explorer for FAT) for work in Windows and Norton Disk Editor 2002 for work in MS-DOS.

I will describe only Disk Explorer for NTFS 3.66 because it is the simplest method and suits our purposes the most.

首先我们需要一个工具把我们的bootloader写入到虚拟的或真实的磁盘中。正好我知道一些免费的、商业的、命令行的、GUI的工具。使用Disk Explorer for NTFS 3.66在windows上运行,使用Norton Disk Editor 2002在MS-DOS上运行。这里我仅仅使用Disk Explorer for NTFS 3.66,因为它使用简单并符合我们的要求。

Testing with the virtual machine VmWare【使用VmWare进行测试】

Creation of the virtual machine【创建虚拟机】

We will need VmWare program version 5.0, 6.0 or higher. To test boot loader we will create the new virtual machine with minimal disk size for example 1 Gb. We format it for NTFS file system. Now we need to map the formatted hard drive to VmWare as the virtual drive. To do it:

我们使用VmWare5.0或更高版本。为测试bootloader,我们创建一个虚拟机,磁盘至少1Gb。我们把它格式化为NTFS文件系统。

 

File->Map or Disconnect Virtual Disks...

After that the window appears. There you should click Map button. In the next appeared window you should set the path to the disk. Now you can also chose the letter for the disk- see Fig.6.
fig6.PNG
Fig.6 – Parameters of virtual disk mapping 

Don’t forget to uncheck the “Open file in read-only mode (recommended)” checkbox. When checked it indicates that the disk should be opened in read-only mode and prevent all recording attempts to avoid data corruption.

After that we can work with the disk of virtual machine as with the usual Windows logical disk. Now we should use Disk Explorer for NTFS 3.66 and record boot loader by the physical offset 0.

Working with Disk Explorer for NTFS【NTFS资源管理器运行】

After program starts we go to our disk (File->Drive). In the window appeared we go to the Logical Drivessection and chose disk with the specified letter (in my case it is Z) – see Fig.7. 
fig7.PNG
Fig.7 – choosing disk in Disk Explorer for NTFS 

Now we use menu item View and As Hex command. It the appeared window we can see the information on the disk represented in the 16-bit view, divided by sectors and offsets. There are only 0s as soon as the disk is empty at the moment. You can see the first sector on the Fig.8.

fig8.PNG
Fig.8 – Sector 1 of the disk

Now we should write our boot loader program to this first sector. We set the marker to position 00 as it is shown on the Fig.8. To copy boot loader we use Edit menu item, Paste from file command. In the opened window we specify the path to the file and click Open. After that the content of the first sector should change and look like it’s shown on the Fig.9 – if you haven’t changed anything in the example code, of course.

You should also write signature 55AAh by the 1FE offset from the sector beginning. If you don’t do it BIOS will check the last two bytes, won’t find the mentioned signature and will consider this sector as not the boot one and won’t read it to the memory.

To switch to the edit mode press F2 and write the necessary numbers –55AAh signature. To leave edit mode press Esc.

Now we need to confirm data writing.

fig9.PNG
Fig.9 – Boot Sector appearance

To apply writing we go to Tools->Options. Window will appear; we go to the Mode item and chose the method of writing - Virtual Write and click Write button – Fig.10.

fig10.PNG
Fig.10 – Choosing writing method in Disk Explorer for NTFS

A great number of routine actions are finished at last and now you can see what we have been developing from the very beginning of this article. Let’s return to the VwWare to disconnect the virtual disk (File->Map or Disconnect Virtual Disks… and click Disconnect).

Let’s execute the virtual machine. We can see now how from the some depth, from the kingdom of machine codes and electrics the familiar string appears ““Hello, world…”, from low-level…” – see Fig.11.

fig11.PNG
Fig.11 – “Hello world…”

Testing on the real hardware【在真实机器上测试】

Testing on the real hardware is almost the same as on the virtual machine except the fact that if something doesn’t work you will need much more time to repair it than to create the new virtual machine. To test boot loader without the threat of existent data corruption (everything can happen), I propose to use flash drive, but first you should reboot your PC, enter BIOS and check if it supports boot from the flash drive. If it does than everything is ok. If it does not than you have to limit your testing to virtual machine test only.

The writing of boot loader to the flash disk in Disk Explorer for NTFS 3.66 is the same to the process for virtual machine. You just should choose the hard drive itself instead of its logical section to perform writing by the correct offset – see Fig.12.

fig12.PNG
Fig.12 – Choosing physical disk as the device

Debug【调试】

If something went wrong – and it usually happens – you need some tools to debug your boot loader. I should say at once that it is very complicated, tiring and time-eating process. You will have to grasp in the Assembler machine codes – so good knowledge of this language is required. Any way I give a list of tools for this purpose:

TD (Turbo Debugger) – great debugger for 16-bit real mode by Borland.

CodeView – good debugger for 16-bit mode by Microsoft.

D86 – good debugger for 16-bit real mode developed by Eric Isaacson – honored veteran of development for Intel processor in Assembler.

Bocsh – program-emulator of virtual machine that includes debugger of machine commands.

Information Sources【拓展】

Assembly Language for Intel-Based Computers” by Kip RIrvine is the great book that gives good knowledge of inner structure of the computer and development in Assembler. You ca also find information about installation, configuration and work with the MASM 6.15 compiler.

This link will guide you to the BIOS interrupt list: http://en.wikipedia.org/wiki/BIOS_interrupt_call

Conclusion【总结】

In this article we have considered what is boot loader, how BIOS works, and how system components interact when system boots. Practical part gave the information about how to develop your own simple boot loader. We demonstrated the mixed code technology and process of automation of assembly with Microsoft Visual Studio 2005, 2008.

Of course it is just a small piece comparing with the huge theme of low-level programming, but if you get interested of this article – it’s great.

See more case studies and research results at Apriorit site.

License【权限】

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL).

这篇文件,模拟了源码和文件的衔接,基于GPOL授权。






posted @ 2016-09-17 11:33  naedzq  阅读(581)  评论(0编辑  收藏  举报