windows或DOS启动的都可以,能讲讲原理吗?
或是任何有帮助的文档,我这方面还每接触过,请大家给我些建议

解决方案 »

  1.   

    那你得对硬盘结构(软盘结构)、PC机的启动原理很了解才行,俺只是知道个大概,不会写
    至于windows的启动盘,也是一样的,只不过后来它会加载自己的GUI界面
      

  2.   

    应该不是很复杂吧,特别是DOS的,需要拷贝的就是那么几个文件,主要是要写引导纪录,一般的磁盘都是1.44m的,笨方法就是拷贝一张现成启动盘的
      

  3.   

    最重要的一点就是,你的程序必须写在磁盘的0磁道,就是让计算机一旦检查设备首先读到的是你的程序,然后就可以进行DOS操作。呵呵,不知道这样说对不对!!
    因为在0磁道好象有保护,一般的拷贝操作读不到那个磁道的数据!
      

  4.   

    并不是直接拷贝几个文件就OK的,而是要自己动手写的那种 - 楼主好像很外行阿,其实启动过程就是通过引导纪录来调用系统的启动文件,在写好引导扇区的时候,只要拷贝相应的文件到相应的位置就可以了,不存在什么拷贝和自己写的问题,当然拷贝的过程可以自己来实现的    如果你是想写自己的启动过程,不使用dos或者window本身的资源,那应该参考linux的实现原码,网上也有很多自己的启动过程可以参考,不过感觉上以楼主现在的基础还需要深造多一些
      

  5.   

    下面是一小部分关于引导程序的,转自http://purec.binghua.com/Article/Class6/Class7/200404/81.html二、认识引导程序BIOS将所检查磁盘的第一个扇区(512B)载入内存,放在0x0000:0x7c00处(见图三),如果个扇区的最后两个字节是“55 AA”,那么这就是一个引导扇区,这个磁盘也就是一块可引导盘。通常这个大小为512B的程序就称为引导程序(boot)。如果最后两个字节不是“55 AA”,那么BIOS就检查下一个磁盘驱动器。通过上面的表述我可可以总结出如下三点引导程序所具有的特点:1.               它的大小是512B,不能多一字节也不能少一字节,因为BIOS只读512B到内存中去。2.               它的结尾两字节必须是“55 AA”,这是引导扇区的标志。3.               它总是放在磁盘的第一个扇区上(0磁头,0磁道,1扇区),因为BIOS只读第一个扇区。(图一)因此,在我们编写引导程序的时候,我们也必须注意上面的三点原则,符合上面三点原则的程序都可以看作是引导程序,至少BIOS是这样认为的,虽然它也许可能是你随意写的一段并没有什么实际意义的代码。因为BIOS一次只读一个扇区也即512字节的数据到内存中,这显然是不够的,现在操作系统都比较庞大,因此我们必须在引导扇区里将存在磁盘上的操作系统的核心部份读进内存,然后再跳转到操作系统的核心部分去执行。
      

  6.   

    楼主如果不是用做拷贝型的那种启动,是不是要做一个自己的IO处理呀?
    那下面这句话就我说错了。
    其实一般人做的启动盘,无外乎就是用微软的DOS引导,然后在批处理里加载自己的程序,让它可以自动运行而已。不知道我这样说的对不对?
      

  7.   

    基本上用C和汇编写,《CSDN开发高手》杂志上有个文章是专门讲这个的,大概在今天第七期。
      

  8.   

    首先要明确处理器(也就是CPU)控制着计算机。对PC而言,启动的时候,CPU都处在实模式状态,相当于只
    是一个Intel 8086处理器。也就是说,即使你现在拥有一个奔腾处理器,它的功能也只能是8086级别。从
    这一点上来讲,可以使用一些软件把处理器转换到著名的保护模式。只有这样,我们才可以充分利用处理
    器的强大功能。 编写操作系统开始是对BIOS控制,取出存储在ROM里的程序。BIOS是用来执行POST(Power On Self Test,
    自检)的。自检是检查计算机的完整性(比如外设是否工作正常、键盘是否连接等)。这一切完成以后,你
    就会听到PC喇叭发出一声清脆的响声。如果一切正常,BIOS就会选择一个启动设备,并且读取该设备的
    第一扇区(即启动扇区),然后控制过程就会转移到指定位置。启动设备可能是一个软盘、光盘、硬盘,
    或者其它所选择的设备。在此我们把软盘作为启动设备。如果我们已经在软盘的启动扇区里写了一些
    代码,这时它就被执行。因此,我们的目的很明确,就是往软盘的启动扇区写一些程序。 首先使用8086汇编来写一个小程序,然后将其拷贝至软盘的启动扇区。为了实现拷贝,要写一个C程序。
    最后,使用软盘启动计算机。 
    需要的工具
    ● as86:这是一个汇编程序,它负责把写的代码转换成目标文件。 ● ld86:这是一个连接器,as86产生的目标代码由它来转换成真正的机器语言。机器语言是8086能够解
    读的形式。 ● GCC:著名的C编程器。因为我们需要写一个C程序将自己的OS转移到软盘中。 ● 一张空软盘:它用于存储编写的操作系统,也是启动设备。 ● 一台装有Linux的计算机:这台机器可以很旧,386、486都可以。 在大部分标准Linux发行版中都会带有as86和ld86。在我使用的Red Hat 7.3中就包含有这两个工具,并且
    在默认的情况下,它已经安装在机器里。如果使用的Linux没有这两个工具,可以从网上下载
    (http://www.cix.co.uk/~mayday/),这两个工具都包含在一个名为bin86的软件包中。此外,有关的文档
    也可以在网上获得(www.linux.org/docs/ldp/howto/Assembly-HOWTO/as86.html)。 
    开始工作
    使用一个你喜欢的编辑器输入以下内容: entry start
    start:
          mov ax,#0xb800
          mov es,ax
          seg es
          mov [0],#0x41
          seg es
          mov [1],#0x1f
    loop1: jmp loop1
     
    这是as86可以读懂的一段汇编程序。第一个句子指明了程序的入口点,声明整个过程从start处开始。
    第二行指明了start的位置,说明整个程序要从start处开始执行。0xb800是显存的开始地址。#表明
    其后是一个立即数。执行语句: mov ax,#oxb800
     
    ax寄存器的值就变为0xb800,这就是显存的地址。下面再将这个值移至es寄存器,es是附加段寄存器。
    请记住8086有一个分段的体系结构。它的各段寄存器为代码段、数据段、堆栈段和附加段,对应的寄
    存器名称分别为cs、ds、ss和es。事实上,我们把显存地址送入了附加段,因此,任何送入附加段的
    东西都会被送到显存中。 要在屏幕上显示字符,就需要向显存中写两个字节。前一个是所要显示字符的ASCⅡ值,第二个字节表
    示该字符的属性。属性包括字符的前景色、背景色及是否闪烁等等。seg es指明下一个将要执行的指令
    是指向es段的。所以,我们把值0x41(在ASCⅡ中表示的字符是A)送到显存的第一个字节中。接下来要把
    字符的属性送到下一个字节当中。在此输入的是0x1f,该属性指的是在蓝色背景下显示白色的字符。因
    此,如果执行这个程序,就可以在屏幕上得到显示在蓝底上的一个白色的A。接着是一个循环。因为在执
    行完显示字符的任务后,要么让程序结束,要么使用一个循环使其永远运行下去。把该文件命名为
    boot.s,然后存盘。 此处显存的概念说得不是很清楚,有必要进一步解释一下。假设屏幕由80列×25行组成,那么第一行
    就需要160字节,其中一个字节用于表示字符,另外一个字节用于表示字符的属性。如果要在第三行
    显示某一字符的话,就要跳过显存的第0和1字节(它们是用于显示第1列的),第2和3字节(它们是用于
    显示第2列的),然后把需要显示字符的ASCⅡ码值入第4字节,把字符的属性写入第5字节。 
    把程序写至启动扇区
    下面写一个C程序,把我的操作系统写入软盘第一扇区。程序内容如下: #include <sys/types.h> /* unistd.h 需要这个文件 */
    #include <unistd.h>    /* 包含有read和write函数 */
    #include <fcntl.h>
    int main()
    {
      char boot_buf[512];
       int floppy_desc, file_desc;
      file_desc = open("./boot", O_RDONLY);
      read(file_desc, boot_buf, 510);
      close(file_desc);
      boot_buf[510] = 0x55;
      boot_buf[511] = 0xaa;
      floppy_desc = open("/dev/fd0", O_RDWR);
      lseek(floppy_desc, 0, SEEK_CUR);
      write(floppy_desc, boot_buf, 512);
      close(floppy_desc);
    }
     
    首先,以只读模式打开boot文件,然后在打开文件时把文件描述符复制到file_desc变量中。从文件中
    读取510个字符,或者读取直到文件结束。在本例中由于文件很小,所以是读取至文件结束。然后关闭
    文件。 最后4行代码打开软盘驱动设备(一般来说是/dev/fd0)。使用lseek找到文件开始处,然后从缓冲中向
    软盘写512个字节。 在read、write、open和lseek的帮助页中,可以看到与函数所有有关的参数及其使用方法。程序中有
    两行比较难懂: boot_buf[510] = 0x55;
    boot_buf[511] = 0xaa;
     
    该信息是用于BIOS的,如果它识别出该设备是一个可启动的设备,那么在第510和511的位置,该值就
    应该是0x55和0xaa。程序会把文件boot读至名为boot_buf的缓冲中。它要求改变第510和第511字节,
    然后把boot_buf写至软盘之上。如果执行代码,软盘上的前512字节就包含了启动代码。最后,把文件
    存为write.c。 
    编译运行
    使用下面的命令把文件变为可执行文件: as86 boot.s -o boot.o
    ld86 -d boot.o -o boot
    cc write.c -o write
     
    首先将boot.s文件编译成目标文件boot.o,然后将该文件连接成最终的boot文件。最后C程序编译成可
    执行的write文件。 插入一个空白软盘,运行以下程序: ./write
      

  9.   

    重新启动电脑,进行BIOS的界面设置,并且把软盘设为第一个启动的设备。然后插入软盘,电脑从软盘
    上启动。 启动完成后,在屏幕上可以看到一个字母A(蓝底白字),启动速度很快,几乎是在瞬间完成。这就意味着
    系统已经从我们制作的软盘上启动了,并且执行了刚才写入启动扇区的程序。现在,它正处在一个无限
    循环的状态。所以,如果想进入Linux,必需拿掉软盘,并且重启机器。 至此,这个操作系统就算完成了,虽然它没有实现什么功能,但是它已经可以启动机器了。 下一期我将在这个启动扇区程序里加入一些代码,使它可以做一些比较复杂的事情(比如使用BIOS中断、
    保护模式切换等等)。 为什么要用BIOS
    BIOS会把启动扇区拷贝至RAM中,并且执行这些代码。除此之外,BIOS还要做很多其它的事情。当一个
    操作系统刚开始启动时,系统中并没有显卡驱动、软盘驱动等任何驱动程序。因此,启动扇区中不可能
    包含任何一个驱动程序,我们要采取其它的途径。这个时候,BIOS就可以帮助我们了。BIOS中包含有各
    种可以使用的程序,包括检测安装的设备、控制打印机、计算内存大小等用于各种目的的程序。这些程
    序就是所说的BIOS中断。 
    如何调用BIOS中断
    在一般的程序设计语言中,函数的调用是一件非常容易的事情。比如在C语言中,如果有一个名为display
    的程序,它带有两个参数,其中参数noofchar表示显示的字符数,参数attr表示显示字符的属性。那么要
    调用它,只需给出程序的名称即可。对于中断的调用,我们使用的是汇编语言中的int指令。 比如,在C语言中要显示一些东西时,使用的指令如下所示: display(nofchar,attr);
     
    而使用BIOS时,要实现相同功能使用的指令如下: int 0x10
     如何传递参数
    在调用BIOS中断之前,我们需要先往寄存器中送一些特定的值。假设要使用BIOS的中断13h,该中断的功
    能是把数据从软盘传送至内存之中。在调用该中断之前,要先指定拷贝数据的段地址,指定驱动器号、
    磁道号、扇区号,以及要传送的扇区数等等。然后,就要往相应的寄存器送入相应的值。在进行下面
    的步骤前,读者有必要对这一点有比较明确地认识。 此外,一个比较重要的事实是同一个中断往往可以实现各种不同的功能。中断所实现的确切功能取决
    于所选择的功能号,功能号一般都存在ah寄存器之中。比如中断13h可以用于读磁盘、写磁盘等功能,
    如果把3送入ah寄存器中,那么中断选择的功能就是写磁盘;如果把2送入ah寄存器中,选择的功能则
    是读磁盘等。 
    我们要做的事情
    这次我们的源代码由两个汇编语言程序和一个C程序组成。第一个汇编文件是引导扇区的代码。在引导扇
    区中,我们写的代码是要把软盘中第二扇区拷贝至内存段的0x500处(地址是0x5000,即偏移地址为0)。
    这时我们需要使用BIOS的中断13h。这时启动扇区的代码就会把控制权转移至0x500处。在第二个汇编文
    件中,代码会使用BIOS中断10h在屏幕上显示一个信息。C程序实现的功能则是把可执行的文件1拷贝至
    启动扇区,把可执行的文件2拷贝至软盘的第二扇区。 
    启动扇区代码
    使用中断13h,启动扇区把软盘第二扇区里的内容加载至内存的0x5000处(段地址为0x500)。下面的代码
    是用于实现这一目的的代码,将其保存至文件sbect.s中。 LOC1=0x500
    entry start
    start:
      mov ax,#LOC1
      mov es,ax
      mov bx,#0 
      mov dl,#0 
      mov dh,#0 
      mov ch,#0 
      mov cl,#2 
      mov al,#1 
      mov ah,#2 
      int 0x13
      jmpi 0,#LOC1
     
    上面代码第一行类似于一个宏。接下去的两行则是把值0x500加载至es寄存器中,这是软盘上第二扇区代
    码将拷贝到的地方(第一扇区是启动扇区)。这时,把段内的偏移设为0。 接下来把驱动器号送入dl寄存器中,其中磁头号送入dl寄存器中,磁道号送入ch寄存器中,扇区号送入
    cl寄存器中,扇区数送入al寄存器之中。我们想要实现的功能是把扇区2、磁道号为0、驱动器号为0的内
    容送至段地址0x500处。所有这些参数都和1.44MB的软盘相对应。 把2送入ah寄存器中,是选择了由中断13h提供的相应功能,即实现从软驱转移数据的功能。 最后调用中断13h,并且转至偏移为0的段地址0x500处。 
    第二个扇区的代码
    第二个扇区中的代码如下所示(把这些代码保存至文件sbect2.s之中): entry start
    start:
      mov     ah,#0x03                
      xor     bh,bh
      int     0x10  mov     cx,#26                  
      mov     bx,#0x0007              
      mov     bp,#mymsg
      mov     ax,#0x1301              
      int     0x10loop1:  jmp     loop1
    mymsg:
      .byte  13,10
      .ascii “Operating System is Loading......”
     
    上面代码将被加载至段地址为0x500处,并且被执行。在这段代码中,使用了中断10h来获取目前的光标位置,然后显示信息。 从第3行到第5行用于得到目前光标的位置,在此中断10h选用的是功能3。然后,清除了bh寄存器的内容,并把字符串送至ch寄存器中。在bx中,我们送入了页码及显示的属性。此处,我们想要在黑背景上显示白色的字符。然后,把要显示字符的地址送到bp之中,信息由两个字节组成,其值分别为13的10,它们分别对应回车和LF(换行)的ASCⅡ值。接下来是一个由29个字符组成的串;在下面实现的功能是输出字符串然后移动光标;最后是调用中断,然后进入循环。 
    C程序代码
    C程序的源代码如下所示,将其存储为write.c文件。 #include <sys/types.h> /* unistd.h needs this */
    #include <unistd.h>    /* contains read/write */
    #include <fcntl.h>
    int main()
    {
      char boot_buf[512];
      int floppy_desc, file_desc;
      file_desc = open(“./bsect”, O_RDONLY);
      read(file_desc, boot_buf, 510);
      close(file_desc);
      boot_buf[510] = 0x55;
      boot_buf[511] = 0xaa;
      floppy_desc = open(“/dev/fd0”, O_RDWR);
      lseek(floppy_desc, 0, SEEK_SET);
      write(floppy_desc, boot_buf, 512);
      file_desc = open(“./sect2”, O_RDONLY);
      read(file_desc, boot_buf, 512);
      close(file_desc);
      lseek(floppy_desc, 512, SEEK_SET);
      write(floppy_desc, boot_buf, 512);
      close(floppy_desc);
    }
      

  10.   

    在上一期中,我曾经介绍过如何操作能启动的软盘。现在这一个过程稍微有点不同,首先把由bsect.s编译出来的可执行文件bsect拷贝至软盘的启动扇区。然后再把由sect2.s产生的可执行文件sect2拷贝至软盘的第二个扇区。 把上述文件置于同一目录之下,然后分别对其进行编译,方法如下所示: as86 bsect.s -o bsect.o
    ld86 -d bsect.o -o bsect
     
    对sect2.s文件重复以上的操作,得出可执行文件sect2。编译write.c,插入软盘后执行write文件,命令如下所示: cc write.c -o write
    ./write
     
    什么是保护模式
    自从1969年推出第一个微处理器以来,Intel处理器就在不断地更新换代,从8086、8088、80286,到80386、80486、奔腾、奔腾Ⅱ、奔腾4等,其体系结构也在不断变化。80386以后,提供了一些新的功能,弥补了8086的一些缺陷。这其中包括内存保护、多任务及使用640KB以上的内存等,并仍然保持和8086家族的兼容性。也就是说80386仍然具备了8086和80286的所有功能,但是在功能上有了很大的增强。早期的处理器是工作在实模式之下的,80286以后引入了保护模式,而在80386以后保护模式又进行了很大的改进。在80386中,保护模式为程序员提供了更好的保护,提供了更多的内存。事实上,保护模式的目的不是为了保护程序,而是要保护程序以外的所有程序(包括操作系统)。 简言之,保护模式是处理器的一种最自然的模式。在这种模式下,处理器的所有指令及体系结构的所有特色都是可用的,并且能够达到最高的性能。 
    保护模式和实模式
    从表面上看,保护模式和实模式并没有太大的区别,二者都使用了内存段、中断和设备驱动来处理硬件,但二者有很多不同之处。我们知道,在实模式中内存被划分成段,每个段的大小为64KB,而这样的段地址可以用16位来表示。内存段的处理是通过和段寄存器相关联的内部机制来处理的,这些段寄存器(CS、DS、SS和ES)的内容形成了物理地址的一部分。具体来说,最终的物理地址是由16位的段地址和16位的段内偏移地址组成的。用公式表示为: 物理地址=左移4位的段地址+偏移地址。 在保护模式下,段是通过一系列被称之为“描述符表”的表所定义的。段寄存器存储的是指向这些表的指针。用于定义内存段的表有两种:全局描述符表(GDT)和局部描述符表(LDT)。GDT是一个段描述符数组,其中包含所有应用程序都可以使用的基本描述符。在实模式中,段长是固定的(为64KB),而在保护模式中,段长是可变的,其最大可达4GB。LDT也是段描述符的一个数组。与GDT不同,LDT是一个段,其中存放的是局部的、不需要全局共享的段描述符。每一个操作系统都必须定义一个GDT,而每一个正在运行的任务都会有一个相应的LDT。每一个描述符的长度是8个字节,格式如图3所示。当段寄存器被加载的时候,段基地址就会从相应的表入口获得。描述符的内容会被存储在一个程序员不可见的影像寄存器(shadow register)之中,以便下一次同一个段可以使用该信息而不用每次都到表中提取。物理地址由16位或者32位的偏移加上影像寄存器中的基址组成。实模式和保护模式的不同可以从图1和图2中很清楚地看出来。 
    图1 实模式的寻址图2 保护模式下的寻址图3 段描述俯的格式
    此外,还有一个中断描述符表(IDT)。这些中断描述符会告诉处理器到那里可以找到中断处理程序。和实模式一样,每一个中断都有一个入口,但是这些入口的格式却完全不同。因为在切换到保护模式的过程中没有使用到IDT,所以在此就不多做介绍了。 
    进入保护模式
    80386有4个32位控制寄存器,名字分别为CR0、CR1、CR2和CR3。CR1是保留在未来处理器中使用的,在80386中没有定义。CR0包含系统的控制标志,用于控制处理器的操作模式和状态。CR2和CR3是用于控制分页机制的。在此,我们关注的是CR0寄存器的PE位控制,它负责实模式和保护模式之间的切换。当PE=1时,说明处理器运行于保护模式之下,其采用的段机制和前面所述的相应内容对应。如果PE=0,那么处理器就工作在实模式之下。 切换到保护模式,实际就是把PE位置为1。为了把系统切换到保护模式,还要做一些其它的事情。程序必须要对系统的段寄存器和控制寄存器进行初始化。把PE位置1后,还要执行跳转指令。过程简述如下: 1.创建GDT表; 2.通过置PE位为1进入保护模式; 3.执行跳转以清除在实模式下读取的任何指令。 下面使用代码来实现这个切换过程。 
    需要的东西
      

  11.   

    制作启动盘的几种有效方法(2003-01-06 10:08:55)
     
    作为一名电脑高手,启动盘绝对是手头必不可少的。启动盘一方面可以在系统崩溃时用做引导系统,然后完成分区、格式化等操作以重新安装系统;另一方面可以启动到DOS实模式下升级BIOS、杀除顽固病毒;还有,当主板不具备光驱引导功能时,可以借助这张启动盘加载通用光驱驱动程序,使用光盘完成系统的安装。 说了半天,可能有些朋友不太明白“启动盘”的用途。其实,它的作用可大着呢! 1.自动加载通用光驱驱动程序:如果你用启动盘启动系统,将会出现启动菜单,选择第一项“StartComputerWithCD-ROMSupport”后,就可以在启动过程中自动加载一个通用光驱驱动程序,这个驱动程序能够识别几乎所有的ATAPIIDE和SCSI光驱,这样就可以访问光盘中的数据啦。 2.自动创建一个虚拟磁盘:一张启动盘的容量局限在1.44MB之内,怎么能够放下许许多多的DOS外部命令和系统诊断工具呢?原来,这些外部命令和系统诊断工具都被压缩在一个名为Ebd.cab的压缩包中,用启动盘启动系统后,它会自动创建一个大小为2MB的虚拟磁盘,然后将所有Ebd.cab包中的文件释放到虚拟磁盘中,此时运行磁盘扫描、分区、格式化等程序的速度将大大加快。 3.CAB压缩包释放工具EXT.EXE:它实际上是EXTRACT.EXE的外壳程序,其作用也是用来释放CAB压缩包中的文件,但使用起来要简单多了。 下面介绍几种制作启动盘的方法。一、在系统安装过程中制作启动盘如果你曾有过安装操作系统的经验,那么一定会记得在安装时会有一个提示:是否创建一张启动盘。你只须插入一张空白的完好软盘,然后点击“确定”按钮就可以创建一张启动盘了。 不过,上面的方法仅仅适用于Windows9X/Me,至于Windows2000/XP,在安装过程中是不会有这一步骤的,我们必须使用专门的制作工具。Windows2000的安装光盘中有一个名为Bootdisk的文件夹,执行其中的makeboot.exe文件,按照提示就可以制作一份需要4张软盘的启动盘;对WindowsXP来说,则需要从http://www.microsoft.com/downloads/release.asp?releaseid=33291(专业版)和http://www.microsoft.com/downloads/release.asp?releaseid=33290(家庭版)下载相应程序,然后才能创建多达6张的启动盘! 二、在“控制面板”中制作启动盘如果由于某种原因,你在安装Windows9X/Me的过程中跳过了启动盘制作这一步骤,也可以启动系统后进入“控制面板-->添加/删除程序”对话框,点击“创建启动盘”按钮即可重新制作一张启动盘,功能与安装过程中制作的启动盘完全相同。不过,你需要插入Windows的安装光盘,未免有些麻烦。 三、在DOS模式下制作启动盘从上面的介绍中可以看到,制作一张启动盘,需要用到Windows的安装光盘,而且要么在安装过程中制作,要么启动系统后制作。但如果我们在安装系统中漏过了启动盘制作这一步骤,但又无法正常进入图形界面,或者已经丢失Windows安装光盘,那该怎么制作启动盘呢?有办法!只要能够进入DOS模式就行,对Windows9X来说,进入Windows\Command文件夹,找到其中一个名为Bootdisk.bat的批处理文件,运行后会出现提示,选择“1”表示在A盘制作启动盘,选择“2”表示在B盘制作启动盘。然后按照屏幕的提示放人一张空白软盘,按下回车键,稍候片刻,就可以得到一张启动盘了。或者,你也可以将\Windows\Command\Ebd文件夹中的所有文件拷贝到软盘中,同样可以得到一张启动盘,但记住拷贝之前请先去除这些文件的系统、隐含、只读属性。 四、快速制作一张干净的启动盘在升级BIOS时一般都会要求制作一张除MSIOS.SYS、IO.SYS、COMMAND.COM3个文件外,不允许有任何驻留内存程序存在的干净启动盘,也就是说不能存在:Autoexec.bat和Config.sys文件,否则会在升级BIOS时提示内存不足的错误。那么,这样的干净启动盘该如何制作呢? 1.DOS模式:很简单,使用“FORMATA:/S”这条DOS命令即可。 2.Windows9X:进入“资源管理器”或“我的电脑”,右击软盘,然后选择“格式化”命令,在对话框中注意勾选“复制系统文件”复选框,然后开始格式化即可。 3.WindowsXP:很幸运,在格式化软盘时,我们仍然可以从对话框中发现这个“创建一个MS-DOS启动盘”的复选框,选择后可以创建一张启动盘。 其实,除了上述方法外,我们还可以利用Windows的备份工具创建紧急恢复盘或自动恢复盘,利用杀毒软件创建DOS启动盘、利用Nero创建可启动光盘等,这里就不多说了。不过,无论你用哪—种方法创建了DOS启动盘,可要记着“扣上”写保护哟。别给病毒进入电脑的机会。 (王荣福 中国网友报) 
      

  12.   

    在Linux下制作启动盘有如下步骤: 1,将一张有ext2文件系统的软盘放入软驱,如果是尚未建立文件系统,则 可以使用命令: mkfs.ext2 /dev/fd0 (假设软盘在A:驱中) 2,将内核拷贝入软盘,可以先使用mount命令软盘挂到系统上,再使用命 令 cp /vmlinuz /mnt/floppy (假设内核文件是/vmlinuz,软盘挂在 /mnt/floppy) 3,打入:rdev /dev/fd0 /dev/hda1 (假设root文件系统在/dev/hda1上)
      

  13.   

    总算有人接上来了。要不发不了继续发没有发完的需要的东西
    ◆ 一张空白软盘 ◆ NASM编译器 下面是整个程序的源代码: org 0x07c00; 起始地址是0000:7c00 
    jmp short begin_boot   ; 跳过其它的数据,跳转到引导程序的开始处
    bootmesg db "Our OS boot sector loading ......"
    pm_mesg  db "Switching to protected mode ...."
    dw 512  ; 每一扇区的字节数
    db 1  ; 每一簇的扇区数
    dw 1  ; 保留的扇区号
    db 2     
    dw 0x00e0     
    dw 0x0b40      
    db 0x0f0     
    dw 9     
    dw 18     
    dw 2  ; 读写扇区号
    dw 0  ; 隐藏扇区号
    print_mesg :
       mov ah,0x13  ; 使用中断10h的功能13,在屏幕上写一个字符串
       mov al,0x00  ; 决定调用函数后光标所处的位置
       mov bx,0x0007    ; 设置显示属性
       mov cx,0x20  ; 在此字符串长度为32 
       mov dx,0x0000    ; 光标的起始行和列
       int 0x10  ; 调用BIOS的中断10h
       ret  ; 返回调用程序
    get_key :
       mov ah,0x00   
       int 0x16  ; Get_key使用中断16h的功能0,读取下一个字符
       ret
    clrscr :
       mov ax,0x0600  ; 使用中断10h的功能6,实现卷屏,如果al=0则清屏
       mov cx,0x0000  ; 清屏
       mov dx,0x174f  ; 卷屏至23,79
       mov bh,0  ; 使用颜色0来填充
       int 0x10  ; 调用10h中断
       ret
    begin_boot :
       call clrscr   ; 先清屏
       mov bp,bootmesg  ; 提供串地址
       call print_mesg  ; 输出信息
       call get_key   ; 等待用户按下任一键
    bits 16
       call clrscr  ; 清屏
       mov ax,0xb800  ; 使gs指向显示内存
       mov gs,ax  ; 在实模式下显示一个棕色的A
       mov word [gs:0],0x641  ; 显示
       call get_key  ; 调用Get_key等待用户按下任一键
       mov bp,pm_mesg  ;  设置串指针
       call print_mesg  ; 调用print_mesg子程序
       call get_key  ; 等待按键
       call clrscr  ; 清屏
       cli  ; 关中断
       lgdt[gdtr]  ; 加载GDT
       mov eax,cr0     
       or al,0x01  ; 设置保护模式位
       mov cr0,eax  ; 将更改后的字送至控制寄存器中
       jmp codesel:go_pm
    bits 32
    go_pm : 
       mov ax,datasel   
       mov ds,ax  ; 初始化ds和es,使其指向数据段
       mov es,ax
       mov ax,videosel  ; 初始化gs,使其指向显示内存
       mov gs,ax
       mov word [gs:0],0x741 ; 在保护模式下显示一个白色的字符A
    spin : jmp spin  ; 循环
    bits 16
    gdtr :
       dw gdt_end-gdt-1  ; gdt的长度
       dd gdt  ; gdt的物理地址
    gdt
    nullsel equ $-gdt  ; $指向当前位置,所以nullsel = 0h
    gdt0  ; 空描述符
       dd 0        
       dd 0  ; 所有的段描述符都是64位的
    codesel equ $-gdt  ; 这是8h也就是gdt的第二个描述符
    code_gdt        
       dw 0x0ffff  ; 段描述符的界限是4Gb
       dw 0x0000       
       db 0x00            
       db 0x09a    
       db 0x0cf    
       db 0x00    
    datasel equ $-gdt    
    data_gdt        
       dw 0x0ffff        
       dw 0x0000        
       db 0x00            
       db 0x092
       db 0x0cf
       db 0x00
    videosel equ $-gdt     
       dw 3999        
       dw 0x8000  ; 基址是0xb8000
       db 0x0b
       db 0x92        
       db 0x00        
       db 0x00
    gdt_end
    times 510-($-$$)  db 0  
    dw 0x0aa55
     
    把上面的代码存在一个名为abc.asm的文件之中,使用命令nasm abc.asm,将得出一个名为abc的文件。然后插入软盘,输入命令:dd if=abc of=/dev/fd0。该命令将把文件abc写入到软盘的第一扇区之中。然后重新启动系统,就会看到如下的信息: *Our os booting................ 
    * A (棕色) 
    * Switching to protected mode.... 
    * A (白色)
     对代码的解释
    上面给出了所有的代码,下面我对上述代码做一些解释。 ◆ 使用的函数 下面是代码中一些函数的说明: print_mesg 该子程序使用了BIOS中断10h的功能13h,即向屏幕写一字符串。属性控制是通过向一些寄存器中送入不同的值来实现的。中断10h是用于各种字符串操作,我们把子功能号13h送到ah中,用于指明要打印一个字符串。al寄存器中的0说明了光标返回的起始位置,0表示调用函数后光标返回到下一行的行首。如果al为1则表示光标位于最后一个字符处。 显存被分成了几页,在同一时刻只能显示其中的一页。bh指明的是页号;bl则指明要显示字符的颜色;cx指明要显示字符串的长度;dx指明光标的位置(即起始的行和列)。所有相关寄存器初始化完成以后,就可以调用BIOS中断10h了。 get_key 使用中断16h的子功能00h,从屏幕得到下一个字符。 clrscr 该函数使用了中断10h的另外一个子功能06h,用于输出开始前清屏。初始化时给al中送入0。寄存器cx和dx指明要清屏的屏幕范围,在本例中是整个屏幕。寄存器bh指明屏幕填充的颜色,在本例中是黑色。 ◆ 其它内容 程序一开始是一条短跳转指令,跳到begin_boot处。在实模式下,在此打印一个棕色的“A”,并且设置一个GDT。切换到保护模式,并且打印一个白色的“A”。这两种模式使用的都是自己的寻址方法。 在实模式下,使用段寄存器gs指示显存位置,我们使用的是CGA显卡(默认基址是0xb8000)。在代码中是不是漏了一个0呢?没有,因为实模式下会提供一个附加的0。这种方式也被80386继承下来了。A的ASCⅡ是0x41,0x06指明了需要一个棕色的字符。该显示会一直持续直至按下任意键。下面要在屏幕上显示一句话,告诉使用者下面马上要进入保护模式了。 启动到保护模式,在进行切换时不希望此时有中断的影响,故要关闭所有的中断(使用cli来实现)。然后对GDT初始化。在整个切换过程中,对4个描述符进行了初始化。这些描述符对代码段(code_gdt)、数据和堆栈段(data_gdt),以及为了访问显存而对显示段进行初始化。此外,还会对一个空描述符进行初始化。 GDT的基址要加载至GDTR系统寄存器之中。gdtr段的第一个字加载的是GDT的大小,在下一个双字中则加载的是基址。然后,lgdt指令把把gdt段加载至GDTR寄存器中。现在已经做好了切换到保护模式前的所有准备。最后一件事情就是把CR0寄存器的PE位置1。不过,即使这样还没有处于保护模式状态之下。 设置了PE位以后,还需要通过执行JMP指令来清除处理器指令预取队列。在80386中,使用指令前总是先将其从内存中取出,并且进行解码和寻址。然而,当进入保护模式以后,预取指令信息(它还处于实地址模式)就无效了。使用JMP指令的目的就是强迫处理器放弃无效的信息。 现在,已经在保护模式下了。那么,如何检测是在保护模式状态之下呢?让我们来看一看屏幕上这个白色的字母A。在这里,使用了数据段选择符(datase1)对数据段和附加段进行了初始化,使用显示段选择符(videose1)对gs进行了初始化。告示的字符“A”其ASCⅡ值和属性位于[gs:0000]处,也就是b8000:0000处。循环语句使得该字符一直在屏幕上显示,直至重新启动系统。 
    下一步要做的事
    现在,这个操作系统已经工作在保护模式下了,但是实际上它并不实现什么具体的功能。你可以在这个基础上为它增加各种操作系统所具有的功能。我们自己动手写操作系统到此也就告一段落。