免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 12551 | 回复: 71
打印 上一主题 下一主题

操作系统学习笔记——引导 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-09-13 14:14 |只看该作者 |正序浏览
由于没有买到《linux设备驱动程序》,但是老天对我还好,买到了本《自己动手写操作系统》,我跟着于渊前辈写的那些内容进行操作,中间有段没有弄明白,所以研究了一阵子,但是后来没有成功,结果就来这里问大家了,现在清楚了,也明白了。(在flw前辈的帮助下)
同时也感谢回答过我的问题的各位牛银!~~
把引导代码帖出来(代码非本人写的,是从书上抄的,把信息改了改)。
  1.         org        07c00h                        ; 告诉编译器程序加载到7c00处
  2.         mov        ax, cs
  3.         mov        ds, ax
  4.         mov        es, ax
  5.         call        DispStr                        ; 调用显示字符串例程
  6.         jmp        $                        ; 无限循环
  7. DispStr:
  8.         mov        ax, BootMessage
  9.         mov        bp, ax                        ; ES:BP = 串地址
  10.         mov        cx, 16                        ; CX = 串长度
  11.         mov        ax, 01301h                ; AH = 13,  AL = 01h
  12.         mov        bx, 000ch                ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
  13.         mov        dl, 0
  14.         int        10h                        ; 10h 号中断
  15.         ret
  16. BootMessage:                db        "QQ:314064349"
  17. times         510-($-$$)        db        0        ; 填充剩下的空间,使生成的二进制代码恰好为512字节
  18. dw         0xaa55                                ; 结束标志
复制代码



用nasm编译成bin,命令
  1. c:\>;cd nasm\bin
  2. c:\>;nasm boot.asm -o boot.bin
复制代码


下面说明一下上面的命令

nasm是一种汇编语言的编译器(可以在win下用,linux下用等很多环境下使用,在baidu中,或者找我要,可以得到)

-o  是nasm里的一个命令参数
用过gcc的朋友会知道,gcc下的命令也如此:
  1. [1jjk@linux.com]$gcc 1jjk.c -o 1jjk
复制代码

这个  -o  和gcc里的 -o意思是一样的,最后的那个boot.bin是生成的目标文件,是二进制文件。

下面说说其他的一些命令:

-o参数:指定输出文件名
-f参数:指定输出文件格式
-l参数:输出列表文件
-E参数:输出错误信息到文件中
-s参数:输出错误信息到屏幕
-i参数:指定头文件路径
-p参数:预编译头文件
-d参数:预编译宏
-u参数:取消宏定义
-e参数:只预处理
-a参数:根本不预处理
-w参数:允许或禁止汇编警告信息

nasm更详细的说明书可以在我的主页里面找到:http://www.zggo.com/xoops
boot.asm是上面的那些汇编语言的源代码文件(在linux源代码会看到),
然后用打开vmware,将“软驱”选项设置为“选用软驱磁盘映像”就可以了,然后把生成的bin放进去就可以了

下面给大家放几张图片看一看!



参考书籍《自己动手写操作系统》作者:于渊

接受建议,改了一下!有笔误,请大家多多指点,多多批评!

4.jpg (39.89 KB, 下载次数: 52)

4.jpg

3.jpg (67.21 KB, 下载次数: 53)

3.jpg

论坛徽章:
0
72 [报告]
发表于 2005-10-18 21:04 |只看该作者

操作系统学习笔记——引导

看到这么多的朋友在研究和讨论

我再加点东东吧!

搜集了一些引导资料

转一下



第二章. 把你的操作系统引导起来

作者:易昭华

什么是操作系统的引导过程?


所谓操作系统的引导过程是将存放在硬盘上的静态的操作系统装载到内存中,并开始执行操作系统的过程。操作系统的整个引导过程应该从计算机上电开始,分为以下几个大步骤:


上电
自检
加载引导扇区
加载操作系统
运行操作系统


引导过程的原理与过程


上电
上电是指按下计算机的电源按钮让计算机开始加电运行。这个过程与计算机的硬件电路关系非常密切,因为计算机加电的第一个状态是由硬件电路决定的,加电后第一个状态主要由计算机处理器(CPU)生产商决定,对于x86系列的CPU,一加电就将指令寄存器设置为:0ffff:0000,表示CPU开始从0ffff:0000这个内存中取出一条指令执行,通常在0ffff:0000处是一条地址转跳指令,转向BIOS的入口。由于BIOS是固化在内存中的,所以,一加电后,CPU可以直接读取BIOS中的指令。




自检
进入BIOS后,BIOS的主要功能包括以下两项:第一项功能是进行计算机自检,第二项功能是加载引导扇区。BIOS进行自检的工作主要是检查计算机是否出现异常,是否可以继续运行下去,这一部分与引导过程本身关系不大,它只是引导过程中的一个步骤,BIOS中与引导关系密切的是上面提到的BIOS的第二项功能,即加载引导扇区,这一项工作的主要内容是把磁盘的引导扇区的内容加载到内存中来,并且转跳到引导程序的第一条指令。




加载引导扇区
硬盘与软盘都有引导扇区,引导扇区就是软盘或硬盘的第一个逻辑扇区,即软盘或硬盘的第0个磁头第0个磁道第1个扇区。软盘的结构比硬盘简单,在软盘上,一般只有一个分区,也就是可以装载一个操作系统,所以在软盘的第一个逻辑扇区就可以把操作系统加载到内存中,而硬盘则不同,由于硬盘的总容量比较大,所以硬盘被分为几个分区,理论上讲每个分区都可以安装一个操作系统,所以在每个分区上都有一个用于加载本分区的引导扇区,因此硬盘的引导扇区比软盘复杂,它不是立即加载操作系统而是加载分区上的引导扇区,然后由分区上的引导扇区加载本分区上的操作系统。在本文以软盘的引导扇区为例来介绍。



软盘的引导扇区是软盘的第一个逻辑扇区,当BIOS的自检过程结束以后,根据BIOS的规范,它下一步要做的工作就是把指定的引导设备(软盘、硬盘、光盘等)上的第一个扇区的内容加载到内存中,并且转跳到加载后的引导扇区的第一条指令。因此我们在开发操作系统引导程序的时候,只要将引导程序直接写如第一个逻辑扇区就可以了,BIOS会自动把它加载到内存中。



加载操作系统
对于软盘来讲,引导扇区中的引导程序就是用于加载操作系统。所谓加载操作系统,也就是把操作系统从磁盘拷贝到内存。因此引导程序首先必须知道操作系统在磁盘的位置,由于此时还没有文件系统,这时引导程序必须通过绝对位置来访问,也就是操作系统在磁盘的开始扇区和结束扇区。操作系统在磁盘的位置与操作系统的安装程序有关,操作系统的安装程序把操作系统从安装盘拷贝到计算机的磁盘上,引导程序把操作系统从磁盘拷贝到内存。




运行操作系统
引导程序把操作系统拷贝到内存后所要做的第一件事就是转跳到操作系统的第一条指令,这样,操作系统就开始运行了。




如何使操作系统引导起来?



要使操作系统引导起来,包括下面的环节:

编写引导程序 (Boot Loader)
制作引导扇 (Boot Sector): 把引导程序写入引导扇区
编写系统加载程序 (OS Loader)
制作系统加载映像 (OS Loader Image)
设置启动设备
第一步:编写引导扇启动程序 (Boot Loader)
这个例子的目标是编写一个运行于PC机上的引导扇启动程序 (Boot Loader) 。



开发语言:C语言和8086汇编语言


开发环境:Borland C++ 3.0

工程文件设置:编译模式为tiny模式
#include "platform.h"
#include "diskstru.h"
extern St_DOS_BootRecord g_stBootRecord;

static BYTE s_bHead;
static BYTE s_bTrack;
static BYTE s_bSector;
static void Lba2CHS(UINT Lba)
{
    _asm mov ax, Lba
        _asm xor dx, dx
        _asm mov bx, g_stBootRecord.BPB.SectorsPerTrack
        _asm div bx
        _asm inc dx
        _asm mov s_bSector, dl
        _asm xor dx, dx
        _asm mov bx, g_stBootRecord.BPB.Sides
        _asm div bx
        _asm mov s_bHead, dl
        _asm mov s_bTrack, al
}

static int pascal ReadSector( void far * lpBuff )
{
        _asm{
        mov ax, word ptr [lpBuff+2]
        mov es, ax
                mov bx, word ptr [lpBuff]
                mov ah, 02h
                mov al, 1
                mov ch, s_bTrack
                mov cl, s_bSector
                mov dh, s_bHead
                mov dl, 0
                int 13h
                jc l_error
                jmp short l_ret
        }
l_error:
                return 0;
l_ret:
                return 1;
}


static const char s_szStarting[] = "Starting Myself Operating system...";
static const char s_szFail[] = "Fail to load OsLoader, system halt.";

static void TextOut(BYTE x, BYTE y, const char * szText, int n)
{
    _asm {
                mov cx, n
                mov dh, y
                mov dl, x
                mov bx, 15
                mov ax, szText
                push bp
                mov bp, ax
                mov ax, 1300h
                int 10h
                pop bp
    }
}

void start(void)
{
        UINT uLba, i;
        BYTE far * lpSect = (BYTE far *)0x80000000;

        //        Clear screen
        _asm{
                mov ax, 3
                int 10h
    }

    //        Display the logo information
        TextOut( 0, 0, s_szStarting, sizeof(s_szStarting)-1 );

        //        Calculate the sector number of the first data sector
        uLba = g_stBootRecord.BPB.ReservedSectors +
                g_stBootRecord.BPB.FAT_Copies * g_stBootRecord.BPB.SectorsPerFAT +
                (g_stBootRecord.BPB.RootDirEntries >;>; 4);

        uLba = 6;
        //        Load the first 128 data sectors into memory at address 8000h:0000h
        for( i = 0; i < 10; i ++ )
        {
                Lba2CHS( uLba );
                if( !ReadSector( lpSect ) )
                {
                        goto l_Fail;
                }

                uLba ++;
                lpSect += 512;
        }

        //  Execute the fetched OS loader at address 8000h:0100h
        _asm {
                mov ax, 0x8000
                mov ds, ax
                mov es, ax
                mov ss, ax
                mov sp, 0xFFF0
                push ax        //push cs
                mov ax, 0x100
                push ax        //push ip(0)
                retf        //        execute OS
        }

l_Fail:
        TextOut( 0, 1, s_szFail, sizeof(s_szFail)-1 );
        for(;;
}

下一步:制作引导扇 (Boot Sector): 把引导程序写入引导扇区
第一步,把编译后的引导转为.com文件,所用的命令如下:tdstrip -c bootsect.exe bootsect.com
第二步,把引导程序写入引导扇区,这一步主要的工具是:DISKEDIT.EXE,操作步骤包括以下几步:
(1) 通过"Object"->;"files"菜单打开.com格式的引导程序
(2) 选择"Tools"->;"Write Object to…"菜单,然后选择"to physical sectors",然后选择第0个磁头,第0个磁道,第1个扇区。

论坛徽章:
0
71 [报告]
发表于 2005-09-22 22:12 |只看该作者

操作系统学习笔记——引导

拉倒吧
看完了啥也不懂!
连啥是CC都不知道
把我弄得
原来CC是一个比较流行的ddos工具

我一直以为是gcc呢
呵呵(搞笑性质的)

论坛徽章:
0
70 [报告]
发表于 2005-09-22 22:11 |只看该作者

操作系统学习笔记——引导

原帖由 "1jjk" 发表:
呵呵

可变参数

是先看printf
vsprintf
write



看完了 Linux 一定懂不了少。。呵呵

论坛徽章:
0
69 [报告]
发表于 2005-09-22 18:26 |只看该作者

操作系统学习笔记——引导

呵呵

可变参数

是先看printf
vsprintf
write

论坛徽章:
0
68 [报告]
发表于 2005-09-22 18:08 |只看该作者

操作系统学习笔记——引导

原帖由 "1jjk" 发表:
呵呵
printf函数就是那么来的啊

我发过的

看了2年
88
我吃饭去了


呵呵..

就这么来的,变出来的..

论坛徽章:
0
67 [报告]
发表于 2005-09-22 18:05 |只看该作者

操作系统学习笔记——引导

呵呵
printf函数就是那么来的啊

我发过的

看了2年
88
我吃饭去了

论坛徽章:
0
66 [报告]
发表于 2005-09-22 17:57 |只看该作者

操作系统学习笔记——引导

原帖由 "1jjk" 发表:
不能这么说
看了全看明白
就知道printf是咋来的了


你看了多长时间?

printf() 是咋来的?

论坛徽章:
0
65 [报告]
发表于 2005-09-22 17:57 |只看该作者

操作系统学习笔记——引导

我就是不服这个事
所以以前C语言
谭浩强,张基温 唐永言 写的那本C
我看了N遍

论坛徽章:
0
64 [报告]
发表于 2005-09-22 17:56 |只看该作者

操作系统学习笔记——引导

看了这么多本书
总结一句话

没有看不懂的书
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP