linux-0.01 boot.s 改编成适合 NASM 语法
来源:互联网 发布:网络医生咨询是真的吗 编辑:程序博客网 时间:2024/06/07 21:38
linux-0.01中的boot.s是使用as86汇编器进行汇编,利用现行的Linux发行版本的as86汇编器进行汇编存在部分语法问题,
主要的语法修改:
0.0 编译成为16实模式为代码,编译起始地址为0
[BITS 16]
[ORG 0x0000]
1.注释 “|” 改为 ";"
2.常量起始标识”#“去掉
2.1 对内存地址addr的内容的引用改为[addr],
如:原格式add ax, sread
改为:add ax,[sread]
3.符号常量定义符号由 ”=“ 改为 EQU
4.为了直接生成binary文件,将如下段说明语句去掉(行首的数字为boot.s中的文件行号)
40 .globl begtext, begdata, begbss, endtext, enddata, endbss
41 .text
42 begtext:
43 .data
44 begdata:
45 .bss
46 begbss:
47 .text
324 .text
325 endtext:
326 .data
327 enddata:
328 .bss
329 endbss:
5. c语言格式的注释换成 NASM 语法的注释,行首加上;
285 /*
286 * This procedure turns off the floppy drive motor, so
287 * that we enter the kernel in a known state, and
288 * don't have to worry about it later.
289 */
6. 294行的outb在NASM中应该改为out dx,al
290 kill_motor:
291 push dx
292 mov dx,#0x3f2
293 mov al,#0
294 outb
295 pop dx
296 ret
7.加入SYSSIZE符号常量的定义
SYSSIZE EQU 0x2000
8.文件为加入启动扇区signature 0x55aa,故将空闲的字节填充为0x00,凑足一个扇区的512个字节
times 510-($-$$) db 0 ; all the rest filled with blank
db 0x55,0xaa
主要的修改就是这些,些微的细节详见下面的代码。
编译命令:nasm boot_nasm.s -l boot_nasm.lst -f bin -o boot.bin
===================改写后的代码===============
;; rewrite the boot.s to fit the NASM syntax
;; snallie@tom.com
;; to make: nasm boot_nasm.s -l boot_nasm.lst -f bin
;; Time-stamp: <root Thursday 09/06/2012 15:15:46>
; 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 its 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 EQU 18
; 1.2Mb disks:
; sectors = 15
; 720kB disks:
; sectors = 9
SYSSIZE EQU 0x2000
BOOTSEG EQU 0x07c0
INITSEG EQU 0x9000
SYSSEG EQU 0x1000
; system loaded at 0x10000 (65536).
ENDSEG EQU SYSSEG + SYSSIZE
[BITS 16]
[ORG 0x0000] ; assembler init address 0000: 7c00
_start:
mov ax,BOOTSEG
mov ds,ax
mov ax,INITSEG
mov es,ax
mov cx,256
sub si,si
sub di,di
rep movsw
jmp INITSEG:go
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 ; 0x8000word=0x10000byte=64KB
jmp 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
dw 0x00eb,0x00eb ; jmp $+2, jmp $+2
out 0xA0,al ; and to 8259A-2
dw 0x00eb,0x00eb
mov al,0x20 ; start of hardware int's (0x20)
out 0x21,al
dw 0x00eb,0x00eb
mov al,0x28 ; start of hardware int's 2 (0x28)
out 0xA1,al
dw 0x00eb,0x00eb
mov al,0x04 ; 8259-1 is master
out 0x21,al
dw 0x00eb,0x00eb
mov al,0x02 ; 8259-2 is slave
out 0xA1,al
dw 0x00eb,0x00eb
mov al,0x01 ; 8086 mode for both
out 0x21,al
dw 0x00eb,0x00eb
out 0xA1,al
dw 0x00eb,0x00eb
mov al,0xFF ; mask off all interrupts for now
out 0x21,al
dw 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;
jmp 8:0 ; jmp offset 0 of segment 8 (cs), ; jmp to 0:0 (head.s startup_32)
; 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:
dw 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: dw 1 ; sectors read of current track
head: dw 0 ; current head
track: dw 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 word [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
out dx,al
pop dx
ret
gdt:
dw 0,0,0,0 ; dummy
dw 0x07FF ; 8Mb - limit=2047 (2048*4096=8Mb)
dw 0x0000 ; base address=0
dw 0x9A00 ; code read/exec
dw 0x00C0 ; granularity=4096, 386
dw 0x07FF ; 8Mb - limit=2047 (2048*4096=8Mb)
dw 0x0000 ; base address=0
dw 0x9200 ; data read/write
dw 0x00C0 ; granularity=4096, 386
idt_48:
dw 0 ; idt limit=0
dw 0,0 ; idt base=0L
gdt_48:
dw 0x800 ; gdt limit=2048, 256 GDT entries
dw gdt,0x9 ; gdt base = 0X9xxxx
msg1:
db 13,10
db "Loading system ..."
db 13,10,13,10
times 510-($-$$) db 0 ; all the rest filled with blank
db 0x55,0xaa
- linux-0.01 boot.s 改编成适合 NASM 语法
- NASM语法
- nasm 语法
- 用nasm重写linux0.0磁盘引导程序boot.s
- Linux/boot/bootsect.S
- Linux/boot/setup.S
- Linux/boot/head.S
- linux boot.s
- /linux/boot/bootsect.s
- /linux/boot/setup.s
- linux-boot-arch_x86_kernel_head_32.S
- nasm重写linux-0.11 head.s (博古以通今)
- nasm assembly 语法
- nasm assembly 语法
- NASM语法知识
- nasm写hello.s
- 静态的dtree改编成动态dtree
- linux汇编工具之GAS(AT&T 语法)和NASM(Intel 语法)比较
- Opengl ES 阴影(shadow)
- Android项目导入出现The type java.lang.Object cannot be resolved.问题解决办法!!
- Android中dip、dp、sp、pt和px的区别
- WebView
- 求python老师一位,周末空闲的
- linux-0.01 boot.s 改编成适合 NASM 语法
- AVSS2012
- 科学计算:Python VS. MATLAB (1)----给我一个理由先
- Cocos2dx create-android-project.bat出现"C:\Program"不是内部命令错误
- matlab与excel连接
- 几个常用控件的笔记
- Qt中的消息通知和事件发送
- 将单instance转换成rac数据库
- Android Socket通信如何设置超时时间