zoukankan      html  css  js  c++  java
  • U盘启动进展

    我们知道操作系统内核是由Loader加载到内存,Loader负责把内核加载到内存,并进行一些必要的系统初始化后,跳转到内核程序。但是Loader并不是CPU首先执行的程序,他之前有BIOS程序,我们就先讲讲BIOS。

    BIOS程序代码被固化在内纯条内,是最底层的程序,直接控制硬件,为加载操作系统做好提前准备工作,主要完成三部分:

    1:系统硬件自检,包括对CPU,640K基本内存,1Mb以上的扩展内存,主板,CMOS存储器,串并口,显卡,软盘、硬盘、键盘等自检过程识别系统拥有哪些硬件,并且对它们进行初始化,并把这些设备信息存储起来。(可见U盘的枚举过程发生在这里)

    2:软件环境设置:BIOS为内核提供一个良好的加载环境,最主要的就是创建中断向量表和存储硬件设备信息。BIOS为内核加载提供了非常有用的和具体硬件打交道的服务子程序(INT 13 磁盘操作,INT 10H屏幕显示,INT 14串口操作,INT 15杂项系统服务,INT 16键盘操作,INT 17并口操作),这些子程序让内核的的加载更加简单有效。可见内核的加载并不用和硬件直接打交道,可以建立在BIOS服务之上,所以说BIOS是硬件上的第一层抽象,是连通硬件与软件的枢纽或者说是硬件与软件的接口。

    BIOS中断大全:http://blog.163.com/zhe_wang_2009/blog/static/1722821212011913675355/

    3:自检与初始化软件环境完成后,便把启动盘0柱面0磁道0扇区上的启动扇区(loader)加载到内存,让其完成内核的加载。

    可见loader在加载内核过程中并不需要直接和硬件打交道,而是在BIOS中断服务程序之上编程(BIOS编程),主要是为了让操作系统的加载与过度更加简单更加简单。

    第一抽象之争:虽然说BIOS是硬件上的第一层抽象,但是操作系统成功加载以后会重新检测初始化硬件,自己重新完成与硬件打交道的服务子程序,BIOS的任何代码任何服务程序便不再使用了,也就是说操作系统并没有建立在BIOS之上,后者只是为操作系统的加载服务的,加载完就没事了,所以我们说操作系统是硬件上的第一层抽象也是没有错误的。

    回到主题,我们再讲U盘启动。U盘启动属于loader的工作,前面讲到loader是在BIOS中断服务之上编程的。

    比如典型的loader代码:

    org 07c00h
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov ax,WrongMessage
    mov bp,ax
    mov cx,30
    mov ax,01301h
    mov bx,000ch
    mov dl,0
    int 10h
    jmp $
    WrongMessage: db "yeah,there is something wrong."
    times 510-($-$$) db 0
    dw 0xaa55

    什么都没做直接调用一个中断,在屏幕上显示一个字符串。

    我们要做U盘启动,首先要做的便是从U盘去数据加载到内存,这里就要用到磁盘处理服务int 13h.

    int 13的使用方法如下:

    ah=0x02 -读磁盘到内存;al=需要读出的扇区数量;

    ch=磁道(柱面号)的低八位;cl=开始扇区(0-5位),磁道号高两位(6-7);

    dh-磁头号;dl=驱动器号(说明:如果是软盘为00h,如果为硬盘为80h,U盘也为80h,BIOS把U盘当成虚拟成硬盘来看待)

    es:bx->指向数据缓冲区;如果读数据出错CF标识置位。

    具体的实验代码如下:

    org 07c00h
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov dx,0080h
    mov cx,0002h
    mov bx,7e00h
    mov ax,0201h
    int 0x13
    jnc OK
    mov ax,WrongMessage
    mov bp,ax
    mov cx,30
    mov ax,01301h
    mov bx,000ch
    mov dl,0
    int 10h
    jmp $
    OK:
    mov ax,7e00h
    mov bp,ax
    mov cx,512
    mov ax,01301h
    mov bx,000ch
    mov dl,0
    int 10h
    jmp $
    WrongMessage: db "yeah,there is something wrong."
    times 510-($-$$) db 0
    dw 0xaa55
    OKMessage : db "Yes I can do it"

    实验步骤:

    nasm boot.asm -o boot.bin 会生成一个528Byte的可执行文件。

    U盘,里面的数据备份一下,你懂得。

    dd if=/dev/sdb of=U.bin bs=1 count=512 

    把u盘原来的loader备份一下。(里面有分区表,掉了也没事,格式化会重新生成)

    dd if=boot.bin of=/dev/sdb bs=1 count=528

    把boot.bin放到优盘里,”Yes I can do it“正好放在第二扇区开始处。

    dd if=U.bin of=/dev/sdb bs=1 count=512 conv=notrunc

    dd if=boot.bin of=/dev/sdb bs=1 count=446 conv=notrunc

    主要为了要U.bin里面的分区表(446-510)

    然后?然后重启机器,设置成U盘启动,屏幕就会打印Yes I can do it。程序主要是把U盘第二扇区内容加载到0000:7e00处并显示它。

    看到的较好的帖子:

    http://bbs.csdn.net/topics/390130256?page=1#post-397068317
    http://bbs.wuyou.com/forum.php?mod=viewthread&tid=127538。这里使用的是基础的int 13功能,还可以使用扩展的int 13功能进行磁盘操作。两者的主要区别:

    以下纯属个人理解,细节部分请上网下载Universal Serial Bus Mass Storage Class UFI Command Specification标准文档(PDF格式)。
    BIOS通过USB总线(2.0的是通过EHCI USB)向USB存储设备发送UFI指令来和它进行交流的。
    其中MODE SENSE Command(5AH)就是你所说的媒体介质、模式检测功能,在返回的数据包中包含了一个Media Type and Write Protect块里面有介质描述符的字节(该字节在格式化的UFI命令包中可以指定),BIOS就是根据这个来确认U盘的类型和是否有写保护等。
    系统对USB存储设备访问是采用一种叫LBA的地址(目前采用的是LBA28),并没有所谓的CHS,windows、linux等访问USB存储设备的时候并不使用BIOS的INT 13H,而是通过USB总线直接发UFI命令包,采用的地址也是LBA,所以就不太存在兼容性问题。
    然而U盘启动引导程序确是依靠BIOS的INT 13H来访问。
    BIOS的INT 13H对U盘的支持(不一定支持),就是把INT 13H中的C、H、S参数转化成LBA地址,然而不同的BIOS设定的每道扇区数、每头柱面数并不一定相同。假设我们有个U盘在自己机子的BIOS被认成16H、512C、64S,分区格式化后,分区的开始位置为0H、1CH、1S,分区引导程序所在的LBA是0000064H,另一台机子的BIOS认成16H、1024C、32S,那么我们刚才做的那个启动盘,分区起始扇区的LBA就变成0000032H,很显然位置错了,当然启动不起来了。
    BIOS对每道扇区数、每头柱面数的不同设置就是导致U盘启动不通用的根本原因。
    也许你会说那么我们引导程序干脆直接使用扩展INT 13H发送LBA包,GRUB就是这种思路,可是有的BIOS并不支持U盘的扩展INT 13H功能,并且在检测的时候还会返回支持的假象-_-!!
    其实386时代的硬盘也遇到这个问题,然而当时CMOS里面提供了硬盘类型参数的手动设置,再加上硬盘不是移动存储设备,所以问题就没那么明显了。
    至于HDD、FDD、ZIP只是媒体介质描述的不同,并不能彻底解决CHS问题。
  • 相关阅读:
    win7下apache+mysql+php安装配置
    mysql -- 外键及数据的完整性
    mysql -- 索引的使用
    mysql 字符类型
    mysql 常用命令
    mysql 时间类型
    URI与URL
    Flask基本问题
    Session和Cookie的区别与联系
    Python flask关于新闻项目业务逻辑梳理
  • 原文地址:https://www.cnblogs.com/zeng2013/p/3636947.html
Copyright © 2011-2022 走看看