LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2515|回复: 7

0.0.1中boot.c中的|后是注释吗?这是什么注释格式?

[复制链接]
发表于 2003-5-10 23:33:42 | 显示全部楼层 |阅读模式
rt!
发表于 2003-5-14 01:10:23 | 显示全部楼层
请问一下,你是不是笔误,我搜索了0.0.1的所有文件,没有boot.c
这个文件。从你说的注解推测,因该是boot.s,而且注解也应该是
在!后吧。这个是at&t汇编语言的注解。
 楼主| 发表于 2003-5-14 13:52:26 | 显示全部楼层
下面是文件boot.c的原码




|
|        boot.s
|
| boot.s is loaded at 0x7c00 by the bios-startup routines, and moves itself
| out of the way to address 0x90000, and jumps there.
|
| It then loads the system at 0x10000, using BIOS interrupts. Thereafter
| it disables all interrupts, moves the system down to 0x0000, changes
| to protected mode, and calls the start of system. System then must
| RE-initialize the protected mode in it's own tables, and enable
| interrupts as needed.
|
| NOTE! currently system is at most 8*65536 bytes long. This should be no
| problem, even in the future. I want to keep it simple. This 512 kB
| kernel size should be enough - in fact more would mean we'd have to move
| not just these start-up routines, but also do something about the cache-
| memory (block IO devices). The area left over in the lower 640 kB is meant
| for these. No other memory is assumed to be "physical", ie all memory
| over 1Mb is demand-paging. All addresses under 1Mb are guaranteed to match
| their physical addresses.
|
| NOTE1 abouve is no longer valid in it's entirety. cache-memory is allocated
| above the 1Mb mark as well as below. Otherwise it is mainly correct.
|
| NOTE 2! The boot disk type must be set at compile-time, by setting
| the following equ. Having the boot-up procedure hunt for the right
| disk type is severe brain-damage.
| The loader has been made as simple as possible (had to, to get it
| in 512 bytes with the code to move to protected mode), and continuos
| read errors will result in a unbreakable loop. Reboot by hand. It
| loads pretty fast by getting whole sectors at a time whenever possible.

| 1.44Mb disks:
sectors = 18
| 1.2Mb disks:
| sectors = 15
| 720kB disks:
| sectors = 9

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

BOOTSEG = 0x07c0
INITSEG = 0x9000
SYSSEG  = 0x1000                        | system loaded at 0x10000 (65536).
ENDSEG        = SYSSEG + SYSSIZE

entry start
start:
        mov        ax,#BOOTSEG
        mov        ds,ax
        mov        ax,#INITSEG
        mov        es,ax
        mov        cx,#256
        sub        si,si
        sub        di,di
        rep
        movw
        jmpi        go,INITSEG
go:        mov        ax,cs
        mov        ds,ax
        mov        es,ax
        mov        ss,ax
        mov        sp,#0x400                | arbitrary value >>512

        mov        ah,#0x03        | read cursor pos
        xor        bh,bh
        int        0x10
       
        mov        cx,#24
        mov        bx,#0x0007        | page 0, attribute 7 (normal)
        mov        bp,#msg1
        mov        ax,#0x1301        | write string, move cursor
        int        0x10

| ok, we've written the message, now
| we want to load the system (at 0x10000)

        mov        ax,#SYSSEG
        mov        es,ax                | segment of 0x010000
        call        read_it
        call        kill_motor

| if the read went well we get current cursor position ans save it for
| posterity.

        mov        ah,#0x03        | read cursor pos
        xor        bh,bh
        int        0x10                | save it in known place, con_init fetches
        mov        [510],dx        | it from 0x90510.
               
| now we want to move to protected mode ...

        cli                        | no interrupts allowed !

| first we move the system to it's rightful place

        mov        ax,#0x0000
        cld                        | 'direction'=0, movs moves forward
do_move:
        mov        es,ax                | destination segment
        add        ax,#0x1000
        cmp        ax,#0x9000
        jz        end_move
        mov        ds,ax                | source segment
        sub        di,di
        sub        si,si
        mov         cx,#0x8000
        rep
        movsw
        j        do_move

| then we load the segment descriptors

end_move:

        mov        ax,cs                | right, forgot this at first. didn't work :-)
        mov        ds,ax
        lidt        idt_48                | load idt with 0,0
        lgdt        gdt_48                | load gdt with whatever appropriate

| that was painless, now we enable A20

        call        empty_8042
        mov        al,#0xD1                | command write
        out        #0x64,al
        call        empty_8042
        mov        al,#0xDF                | A20 on
        out        #0x60,al
        call        empty_8042

| well, that went ok, I hope. Now we have to reprogram the interrupts :-(
| we put them right after the intel-reserved hardware interrupts, at
| int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
| messed this up with the original PC, and they haven't been able to
| rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
| which is used for the internal hardware interrupts as well. We just
| have to reprogram the 8259's, and it isn't fun.

        mov        al,#0x11                | initialization sequence
        out        #0x20,al                | send it to 8259A-1
        .word        0x00eb,0x00eb                | jmp $+2, jmp $+2
        out        #0xA0,al                | and to 8259A-2
        .word        0x00eb,0x00eb
        mov        al,#0x20                | start of hardware int's (0x20)
        out        #0x21,al
        .word        0x00eb,0x00eb
        mov        al,#0x28                | start of hardware int's 2 (0x28)
        out        #0xA1,al
        .word        0x00eb,0x00eb
        mov        al,#0x04                | 8259-1 is master
        out        #0x21,al
        .word        0x00eb,0x00eb
        mov        al,#0x02                | 8259-2 is slave
        out        #0xA1,al
        .word        0x00eb,0x00eb
        mov        al,#0x01                | 8086 mode for both
        out        #0x21,al
        .word        0x00eb,0x00eb
        out        #0xA1,al
        .word        0x00eb,0x00eb
        mov        al,#0xFF                | mask off all interrupts for now
        out        #0x21,al
        .word        0x00eb,0x00eb
        out        #0xA1,al

| well, that certainly wasn't fun :-(. Hopefully it works, and we don't
| need no steenking BIOS anyway (except for the initial loading :-).
| The BIOS-routine wants lots of unnecessary data, and it's less
| "interesting" anyway. This is how REAL programmers do it.
|
| Well, now's the time to actually move into protected mode. To make
| things as simple as possible, we do no register set-up or anything,
| we let the gnu-compiled 32-bit programs do that. We just jump to
| absolute address 0x00000, in 32-bit protected mode.

        mov        ax,#0x0001        | protected mode (PE) bit
        lmsw        ax                | This is it!
        jmpi        0,8                | jmp offset 0 of segment 8 (cs)

| This routine checks that the keyboard command queue is empty
| No timeout is used - if this hangs there is something wrong with
| the machine, and we probably couldn't proceed anyway.
empty_8042:
        .word        0x00eb,0x00eb
        in        al,#0x64        | 8042 status port
        test        al,#2                | is input buffer full?
        jnz        empty_8042        | yes - loop
        ret

| This routine loads the system at address 0x10000, making sure
| no 64kB boundaries are crossed. We try to load it as fast as
| possible, loading whole tracks whenever we can.
|
| in:        es - starting address segment (normally 0x1000)
|
| This routine has to be recompiled to fit another drive type,
| just change the "sectors" variable at the start of the file
| (originally 18, for a 1.44Mb drive)
|
sread:        .word 1                        | sectors read of current track
head:        .word 0                        | current head
track:        .word 0                        | current track
read_it:
        mov ax,es
        test ax,#0x0fff
die:        jne die                        | es must be at 64kB boundary
        xor bx,bx                | bx is starting address within segment
rp_read:
        mov ax,es
        cmp ax,#ENDSEG                | have we loaded all yet?
        jb ok1_read
        ret
ok1_read:
        mov ax,#sectors
        sub ax,sread
        mov cx,ax
        shl cx,#9
        add cx,bx
        jnc ok2_read
        je ok2_read
        xor ax,ax
        sub ax,bx
        shr ax,#9
ok2_read:
        call read_track
        mov cx,ax
        add ax,sread
        cmp ax,#sectors
        jne ok3_read
        mov ax,#1
        sub ax,head
        jne ok4_read
        inc track
ok4_read:
        mov head,ax
        xor ax,ax
ok3_read:
        mov sread,ax
        shl cx,#9
        add bx,cx
        jnc rp_read
        mov ax,es
        add ax,#0x1000
        mov es,ax
        xor bx,bx
        jmp rp_read

read_track:
        push ax
        push bx
        push cx
        push dx
        mov dx,track
        mov cx,sread
        inc cx
        mov ch,dl
        mov dx,head
        mov dh,dl
        mov dl,#0
        and dx,#0x0100
        mov ah,#2
        int 0x13
        jc bad_rt
        pop dx
        pop cx
        pop bx
        pop ax
        ret
bad_rt:        mov ax,#0
        mov dx,#0
        int 0x13
        pop dx
        pop cx
        pop bx
        pop ax
        jmp read_track

/*
* This procedure turns off the floppy drive motor, so
* that we enter the kernel in a known state, and
* don't have to worry about it later.
*/
kill_motor:
        push dx
        mov dx,#0x3f2
        mov al,#0
        outb
        pop dx
        ret

gdt:
        .word        0,0,0,0                | dummy

        .word        0x07FF                | 8Mb - limit=2047 (2048*4096=8Mb)
        .word        0x0000                | base address=0
        .word        0x9A00                | code read/exec
        .word        0x00C0                | granularity=4096, 386

        .word        0x07FF                | 8Mb - limit=2047 (2048*4096=8Mb)
        .word        0x0000                | base address=0
        .word        0x9200                | data read/write
        .word        0x00C0                | granularity=4096, 386

idt_48:
        .word        0                        | idt limit=0
        .word        0,0                        | idt base=0L

gdt_48:
        .word        0x800                | gdt limit=2048, 256 GDT entries
        .word        gdt,0x9                | gdt base = 0X9xxxx
       
msg1:
        .byte 13,10
        .ascii "Loading system ..."
        .byte 13,10,13,10

.text
endtext:
.data
enddata:
.bss
endbss:
发表于 2003-5-15 21:50:44 | 显示全部楼层
注意,你看到开头的注解了吗?是boot.s
发表于 2003-5-15 21:52:57 | 显示全部楼层

自己对boot.s做的一点注解。

bootsect.s (c) 1991, 1992 Linus Torvalds 版权所有 !

bootsect.s 被bios-启动子程序加载至0x7c00 (31k)处,并将自己移到了地址0x90000(576k)处,并跳转至那里。
但不能盲目地跳转,有些系统可能只有512k的低内存。使用中断0x12来获得(系统的)最高内存等。
并将系统加载到地址0x10000处。注意!目前的内核系统最大长度限制为(8*65536-4096)(508k)字节长,
即使是在将来这也是没有问题的。我想让它保持简单明了。这样508k的最大内核长度应该是足够了。
(尤其是这里没有象minix中一样包含缓冲区高速缓冲,而且尤其是现在内核是压缩的):-)
加载程序已经做的尽量地简单了,所以持续的读出错将导致死循环。只能手工重启。只要可能,通过一次取得整个磁道,加载过程可以做的很快的。



此处为磁盘参数的定义:

许多BIOS的默认磁盘参数表将不能进行扇区数大于在表中指定的最大扇区数
( - 在某些情况下这意味着是7个扇区)后面的多扇区的读操作。由于单个扇
区的读操作是很慢的而且当然是没问题的,* 我们必须在RAM中(为第一个磁盘)
创建新的参数表。我们将把最大扇区数设置为18 - 我们在一个FD 1.44驱动器
上所能遇到的最大值。此值太高是没有任何害处的,但是低的话就会有问题了。
(注:如果是ED 2.88的驱动器,就该把最大扇区数设置为36,后续版本有此设置)

| 1.44Mb disks: sectors = 18
| 1.2Mb disks: sectors = 15
| 720kB disks: sectors = 9

.globl begtext, begdata, begbss, endtext, enddata, endbss

.text begtext:

.data begdata:

.bss begbss:

.text

BOOTSEG = 0x07c0 |bootsect的原始地址,这里大家不会陌生吧;

INITSEG = 0x9000 |呵呵,可爱的boot把自己搬家到这里了;

SYSSEG  = 0x1000 |系统加载至0x1000(65536)(64k)段处;


ENDSEG  = SYSSEG + SYSSIZE |系统的大小 0x4000(16k)是>=bootsect + 堆栈的长度的任意的值

entry start start:

    mov ax,#BOOTSEG |将ds段寄存器置为0x7C0;

    mov ds,ax

    mov ax,#INITSEG |将es段寄存器置为0x9000(呵呵,搬家了);

    mov es,ax

    mov cx,#256 |将cx计数器置为256(要移动256个字, 512字节);

    sub si,si |源地址 ds:si=0x07C0:0x0000;

    sub di,di |目的地址es:di=0x9000:0x0000;

    rep |将这段程序从0x7C0:0(31k)移至0x9000:0(576k)处;

    movw |共256个字(512字节)(0x200长);

    jmpi    go,INITSEG |间接跳转至移动后的本程序go处;



go: mov ax,cs |这个时候ax和es现在已经含有INITSEG的值(0x9000);

    mov ds,ax |置ds数据段为0x9000

    mov es,ax |置es数据段为0x9000

    mov ss,ax |置ss数据段为0x9000

    mov sp,#0x400 |置堆栈指针INITSEG:0x4000-12处;

|从这里开始打印一些无用的信息

    mov ah,#0x03 |读光标的位置;

    xor bh,bh |

    int 0x10

    mov cx,#24

    mov bx,#0x0007  |页0,属性7 (normal)

    mov bp,#msg1

    mov ax,#0x1301  |写字符串,移动光标;

    int 0x10

|ok, 我们已经显示出了信息,现在我们要加载系统了(到0x10000处)(64k处),let's go go go!

    mov ax,#SYSSEG

    mov es,ax       |es=0x01000的段

    call    read_it |读system,es为输入参数;

    call    kill_motor |啊哦,关闭驱动器马达了。。。

|中断服务int 10h的第13h号功能,在萤幕上输出字串"Loading",这个字串在boot linux时都会首先被看到,相信大家应该觉得很眼熟吧。


    mov ah,#0x03

    xor bh,bh

    int 0x10

    mov [510],dx

|大家请注意,为了大家的安全现在进入保护模式 :-)

    cli         |这个老朋友很熟悉啦,无外呼很温柔的告诉你,现在不能中断了哦,中断被它屏蔽掉了。

|好吧,现在把系统加载到正确的地方!(也就是0x0000)

    mov ax,#0x0000

    cld         | 'direction'=0, movs moves forward

|怎么看boot也像个搬运工,现在又将核心从0x10000处移至0x1000处;

do_move:

    mov es,ax       | destination segment

    add ax,#0x1000

    cmp ax,#0x9000

    jz  end_move

    mov ds,ax       | source segment

    sub di,

    sub si,si

    mov     cx,#0x8000

    rep

    movsw

    j   do_move

| then we load the segment descriptors

end_move:

    mov ax,cs       | 对了,不要忘记先要做这一步哦,不然怎么工作? :-)

    mov ds,ax

    lidt    idt_48      | load idt with 0,0

    lgdt    gdt_48      | load gdt with whatever appropriate

|打开A20这条线吧,不然1M以上的MEMORY怎么工作呢:-)

    call    empty_8042
    mov al,#0xD1 |在这里发号司令!
    out #0x64,al
    call    empty_8042
    mov al,#0xDF |yes sir!打开了!
    out #0x60,al
    call    empty_8042

|好了,如果一切顺利,到这里,就不得不改变一下中断的定义了,我们直接利用INTEL类CPU的保留中断0x20到0x2F不能很好的工作,
|那是因为被IBM最先的原始定义弄乱了,到后来又得没有得到纠正。因此,BISO中的0x08到0x0f还是用内部硬件中断,
|我们只修改8259芯片的中断控制程序。(本人E文水平有限,以下是原文,在后续版本中中断的初始化是放在[arch/i386/kernel/i8259.c]中的)

| well, that went ok, I hope. Now we have to reprogram the interrupts :-(
| we put them right after the intel-reserved hardware interrupts, at
| int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
| messed this up with the original PC, and they haven't been able to
| rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
| which is used for the internal hardware interrupts as well. We just
| have to reprogram the 8259's, and it isn't fun.

    mov al,#0x11        |初始化序列;
    out #0x20,al        |发送给8259A-1
    .word   0x00eb,0x00eb       |跳转 $+2, jmp $+2
    out #0xA0,al        |发送给8259A-2
    .word   0x00eb,0x00eb
    mov al,#0x20        |开始的硬件中断(0x20)
    out #0x21,al
    .word   0x00eb,0x00eb
    mov al,#0x28        |开始的硬件中断 2 (0x28)
    out #0xA1,al
    .word   0x00eb,0x00eb
    mov al,#0x04        | 8259-1 为主
    out #0x21,al
    .word   0x00eb,0x00eb
    mov al,#0x02        | 8259-2 为从
    out #0xA1,al
    .word   0x00eb,0x00eb
    mov al,#0x01        | 8086 双模式
    out #0x21,al
    .word   0x00eb,0x00eb
    out #0xA1,al
    .word   0x00eb,0x00eb
    mov al,#0xFF        | 屏蔽所有的中断
    out #0x21,al
    .word   0x00eb,0x00eb
    out #0xA1,al

| well, that certainly wasn't fun :-(. Hopefully it works, and we
don't | need no steenking BIOS anyway (except for the initial
loading :-). | The BIOS-routine wants lots of unnecessary data,
and it's less | "interesting" anyway. This is how REAL programmers
do it. | | Well, now's the time to actually move into protected
mode. To make | things as simple as possible, we do no register
set-up or anything, | we let the gnu-compiled 32-bit programs do
that. We just jump to | absolute address 0x00000, in 32-bit
protected mode.

    mov ax,#0x0001  | protected mode (PE) bit
    lmsw    ax      | This is it!
    jmpi    0,8     | jmp offset 0 of segment 8 (cs)

| This routine checks that the keyboard command queue is empty |
No timeout is used - if this hangs there is something wrong with |
the machine, and we probably couldn't proceed anyway. empty_8042:
    .word   0x00eb,0x00eb
    in  al,#0x64    | 8042 status port
    test    al,#2       | is input buffer full?
    jnz empty_8042  | yes - loop
    ret

| This routine loads the system at address 0x10000, making sure |
no 64kB boundaries are crossed. We try to load it as fast as |
possible, loading whole tracks whenever we can. | | in:   es -
starting address segment (normally 0x1000) | | This routine has to
be recompiled to fit another drive type, | just change the
"sectors" variable at the start of the file | (originally 18, for
a 1.44Mb drive) | sread:  .word 1         | sectors read of
current track head:   .word 0         | current head track:  .word
0         | current track read_it:
    mov ax,es
    test ax,#0x0fff
die:    jne die         | es must be at 64kB boundary
    xor bx,bx       | bx is starting address within segment
rp_read:
    mov ax,es
    cmp ax,#ENDSEG      | have we loaded all yet?
    jb ok1_read
    ret
ok1_read:
    mov ax,#sectors
    sub ax,sread
    mov cx,ax
    shl cx,#9
    add cx,bx
    jnc ok2_read
    je ok2_read
    xor ax,ax
    sub ax,bx
    shr ax,#9
ok2_read:
    call read_track
    mov cx,ax
    add ax,sread
    cmp ax,#sectors
    jne ok3_read
    mov ax,#1
    sub ax,head
    jne ok4_read
    inc track
ok4_read:
    mov head,ax
    xor ax,ax
ok3_read:
    mov sread,ax
    shl cx,#9
    add bx,cx
    jnc rp_read
    mov ax,es
    add ax,#0x1000
    mov es,ax
    xor bx,bx
    jmp rp_read

read_track:
    push ax
    push bx
    push cx
    push dx
    mov dx,track
    mov cx,sread
    inc cx
    mov ch,dl
    mov dx,head
    mov dh,dl
    mov dl,#0
    and dx,#0x0100
    mov ah,#2
    int 0x13
    jc bad_rt
    pop dx
    pop cx
    pop bx
    pop ax
    ret
bad_rt: mov ax,#0
    mov dx,#0
    int 0x13
    pop dx
    pop cx
    pop bx
    pop ax
    jmp read_track

/*

* This procedure turns off the floppy drive motor, so

* that we enter the kernel in a known state, and

* don't have to worry about it later.

*/

kill_motor:

    push dx

    mov dx,#0x3f2

    mov al,#0

    outb

    pop dx

    ret

gdt:

    .word   0,0,0,0     | dummy

    .word   0x07FF      | 8Mb - limit=2047 (2048*4096=8Mb)

    .word   0x0000      | base address=0

    .word   0x9A00      | code read/exec

    .word   0x00C0      | granularity=4096, 386

    .word   0x07FF      | 8Mb - limit=2047 (2048*4096=8Mb)

    .word   0x0000      | base address=0

    .word   0x9200      | data read/write

    .word   0x00C0      | granularity=4096, 386

idt_48:

    .word   0           | idt limit=0

    .word   0,0         | idt base=0L

gdt_48:

    .word   0x800       | gdt limit=2048, 256 GDT entries

    .word   gdt,0x9     | gdt base = 0X9xxxx

msg1:

    .byte 13,10

    .ascii "Loading system ..."

    .byte 13,10,13,10


.text endtext: .data enddata: .bss endbss:
 楼主| 发表于 2003-5-16 12:34:19 | 显示全部楼层
就是不明白前面的那个竖条是做什么用的吗
发表于 2003-5-16 20:30:33 | 显示全部楼层
最初由 有影 发表
请问一下,你是不是笔误,我搜索了0.0.1的所有文件,没有boot.c
这个文件。从你说的注解推测,因该是boot.s,而且注解也应该是
在!后吧。这个是at&t汇编语言的注解。


仔细看看,我已经回复了。
 楼主| 发表于 2003-5-17 09:50:41 | 显示全部楼层
这些竖条后的注解可以通过编译器的过滤吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表