您的位置:首页 > 其它

bootsect.S (读核笔记系列)

2005-10-08 20:26 267 查看
这个程序是引导程序。

按照早期Intel和微机和DOS的约定,机器开启后,由它的ROM BIOS将启动盘的第一扇区(Boot sector)512个字节装入物理内存的0X7C00处,然后跳转到0X7C00开始引导程序的执行。

所以,第一扇区的内容就是Bootsect,是在创建系统盘时由Linux操作系统写入的。

当你看下面的代码时,你要明白一点,Bootsect
的任务就是将操作系统内核从引导盘上读到内存中,并将它摆放在内存的适当位置。bootsect读入的内容包括Setup(在下一节中要讲到的)程序和一
个经过压缩的内核映像zImage或bzImage.(如果你有电脑,建议去装装Linux,并且去学习编译内核,这样你会有很多感性的认识。)

好了,下面把bootsect.S代码贴出来:
有两个,可以对照看:第一个是linux0.11的,第二个是我现在用的系统linux-2.6.11-6,其中代码已有不少改动。好了!
第一个:
1 !
2 ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
3 ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
4 ! versions of linux
5 !
6 SYSSIZE = 0x3000
7 !
8 ! bootsect.s (C) 1991 Linus Torvalds
9 !
10 ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
11 ! iself out of the way to address 0x90000, and jumps there.
12 !
13 ! It then loads 'setup' directly after itself (0x90200), and the system
14 ! at 0x10000, using BIOS interrupts.
15 !
16 ! NOTE! currently system is at most 8*65536 bytes long. This should be no
17 ! problem, even in the future. I want to keep it simple. This 512 kB
18 ! kernel size should be enough, especially as this doesn't contain the
19 ! buffer cache as in minix
20 !
21 ! The loader has been made as simple as possible, and continuos
22 ! read errors will result in a unbreakable loop. Reboot by hand. It
23 ! loads pretty fast by getting whole sectors at a time whenever possible.
24
25 .globl begtext, begdata, begbss, endtext, enddata, endbss
26 .text
27 begtext:
28 .data
29 begdata:
30 .bss
31 begbss:
32 .text
33
34 SETUPLEN = 4 ! nr of setup-sectors
35 BOOTSEG = 0x07c0 ! original address of boot-sector
36 INITSEG = 0x9000 ! we move boot here - out of the way
37 SETUPSEG = 0x9020 ! setup starts here
38 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
39 ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
40
41 ! ROOT_DEV: 0x000 - same type of floppy as boot.
42 ! 0x301 - first partition on first drive etc
43 ROOT_DEV = 0x306
44
45 entry start
46 start:
47 mov ax,#BOOTSEG
48 mov ds,ax
49 mov ax,#INITSEG
50 mov es,ax
51 mov cx,#256
52 sub si,si
53 sub di,di
54 rep
55 movw
56 jmpi go,INITSEG
57 go: mov ax,cs
58 mov ds,ax
59 mov es,ax
60 ! put stack at 0x9ff00.
61 mov ss,ax
62 mov sp,#0xFF00 ! arbitrary value >>512
63
64 ! load the setup-sectors directly after the bootblock.
65 ! Note that 'es' is already set up.
66
67 load_setup:
68 mov dx,#0x0000 ! drive 0, head 0
69 mov cx,#0x0002 ! sector 2, track 0
70 mov bx,#0x0200 ! address = 512, in INITSEG
71 mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
72 int 0x13 ! read it
73 jnc ok_load_setup ! ok - continue
74 mov dx,#0x0000
75 mov ax,#0x0000 ! reset the diskette
76 int 0x13
77 j load_setup
78
79 ok_load_setup:
80
81 ! Get disk drive parameters, specifically nr of sectors/track
82
83 mov dl,#0x00
84 mov ax,#0x0800 ! AH=8 is get drive parameters
85 int 0x13
86 mov ch,#0x00
87 seg cs
88 mov sectors,cx
89 mov ax,#INITSEG
90 mov es,ax
91
92 ! Print some inane message
93
94 mov ah,#0x03 ! read cursor pos
95 xor bh,bh
96 int 0x10
97
98 mov cx,#24
99 mov bx,#0x0007 ! page 0, attribute 7 (normal)
100 mov bp,#msg1
101 mov ax,#0x1301 ! write string, move cursor
102 int 0x10
103
104 ! ok, we've written the message, now
105 ! we want to load the system (at 0x10000)
106
107 mov ax,#SYSSEG
108 mov es,ax ! segment of 0x010000
109 call read_it
110 call kill_motor
111
112 ! After that we check which root-device to use. If the device is
113 ! defined (!= 0), nothing is done and the given device is used.
114 ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
115 ! on the number of sectors that the BIOS reports currently.
116
117 seg cs
118 mov ax,root_dev
119 cmp ax,#0
120 jne root_defined
121 seg cs
122 mov bx,sectors
123 mov ax,#0x0208 ! /dev/ps0 - 1.2Mb
124 cmp bx,#15
125 je root_defined
126 mov ax,#0x021c ! /dev/PS0 - 1.44Mb
127 cmp bx,#18
128 je root_defined
129 undef_root:
130 jmp undef_root
131 root_defined:
132 seg cs
133 mov root_dev,ax
134
135 ! after that (everyting loaded), we jump to
136 ! the setup-routine loaded directly after
137 ! the bootblock:
138
139 jmpi 0,SETUPSEG
140
141 ! This routine loads the system at address 0x10000, making sure
142 ! no 64kB boundaries are crossed. We try to load it as fast as
143 ! possible, loading whole tracks whenever we can.
144 !
145 ! in: es - starting address segment (normally 0x1000)
146 !
147 sread: .word 1+SETUPLEN ! sectors read of current track
148 head: .word 0 ! current head
149 track: .word 0 ! current track
150
151 read_it:
152 mov ax,es
153 test ax,#0x0fff
154 die: jne die ! es must be at 64kB boundary
155 xor bx,bx ! bx is starting address within segment
156 rp_read:
157 mov ax,es
158 cmp ax,#ENDSEG ! have we loaded all yet?
159 jb ok1_read
160 ret
161 ok1_read:
162 seg cs
163 mov ax,sectors
164 sub ax,sread
165 mov cx,ax
166 shl cx,#9
167 add cx,bx
168 jnc ok2_read
169 je ok2_read
170 xor ax,ax
171 sub ax,bx
172 shr ax,#9
173 ok2_read:
174 call read_track
175 mov cx,ax
176 add ax,sread
177 seg cs
178 cmp ax,sectors
179 jne ok3_read
180 mov ax,#1
181 sub ax,head
182 jne ok4_read
183 inc track
184 ok4_read:
185 mov head,ax
186 xor ax,ax
187 ok3_read:
188 mov sread,ax
189 shl cx,#9
190 add bx,cx
191 jnc rp_read
192 mov ax,es
193 add ax,#0x1000
194 mov es,ax
195 xor bx,bx
196 jmp rp_read
197
198 read_track:
199 push ax
200 push bx
201 push cx
202 push dx
203 mov dx,track
204 mov cx,sread
205 inc cx
206 mov ch,dl
207 mov dx,head
208 mov dh,dl
209 mov dl,#0
210 and dx,#0x0100
211 mov ah,#2
212 int 0x13
213 jc bad_rt
214 pop dx
215 pop cx
216 pop bx
217 pop ax
218 ret
219 bad_rt: mov ax,#0
220 mov dx,#0
221 int 0x13
222 pop dx
223 pop cx
224 pop bx
225 pop ax
226 jmp read_track
227
228 /*
229 * This procedure turns off the floppy drive motor, so
230 * that we enter the kernel in a known state, and
231 * don't have to worry about it later.
232 */
233 kill_motor:
234 push dx
235 mov dx,#0x3f2
236 mov al,#0
237 outb
238 pop dx
239 ret
240
241 sectors:
242 .word 0
243
244 msg1:
245 .byte 13,10
246 .ascii "Loading system "
247 .byte 13,10,13,10
248
249 .org 508
250 root_dev:
251 .word ROOT_DEV
252 boot_flag:
253 .word 0xAA55
254
255 .text
256 endtext:
257 .data
258 enddata:
259 .bss
260 endbss:
261
第二个:(头文件贴在最下面!)
1 /*
2 * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
3 *
4 * modified by Drew Eckhardt
5 * modified by Bruce Evans (bde)
6 * modified by Chris Noe (May 1999) (as86 -> gas)
7 * gutted by H. Peter Anvin (Jan 2003)
8 *
9 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
10 * addresses must be multiplied by 16 to obtain their respective linear
11 * addresses. To avoid confusion, linear addresses are written using leading
12 * hex while segment addresses are written as segment:offset.
13 *
14 */
15
16 #include <asm/boot.h>
17
18 SETUPSECTS = 4 /* default nr of setup-sectors */
19 BOOTSEG = 0x07C0 /* original address of boot-sector */
20 INITSEG = DEF_INITSEG /* we move boot here - out of the way */
21 SETUPSEG = DEF_SETUPSEG /* setup starts here */
22 SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
23 SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
24 /* to be loaded */
25 ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
26 SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
27
28 #ifndef SVGA_MODE
29 #define SVGA_MODE ASK_VGA
30 #endif
31
32 #ifndef RAMDISK
33 #define RAMDISK 0
34 #endif
35
36 #ifndef ROOT_RDONLY
37 #define ROOT_RDONLY 1
38 #endif
39
40 .code16
41 .text
42
43 .global _start
44 _start:
45
46 # Normalize the start address
47 jmpl $BOOTSEG, $start2
48
49 start2:
50 movw %cs, %ax
51 movw %ax, %ds
52 movw %ax, %es
53 movw %ax, %ss
54 movw $0x7c00, %sp
55 sti
56 cld
57
58 movw $bugger_off_msg, %si
59
60 msg_loop:
61 lodsb
62 andb %al, %al
63 jz die
64 movb $0xe, %ah
65 movw $7, %bx
66 int $0x10
67 jmp msg_loop
68
69 die:
70 # Allow the user to press a key, then reboot
71 xorw %ax, %ax
72 int $0x16
73 int $0x19
74
75 # int 0x19 should never return. In case it does anyway,
76 # invoke the BIOS reset code
77 ljmp $0xf000,$0xfff0
78
79
80 bugger_off_msg:
81 .ascii "Direct booting from floppy is no longer supported.\r\n"
82 .ascii "Please use a boot loader program instead.\r\n"
83 .ascii "\n"
84 .ascii "Remove disk and press any key to reboot . . .\r\n"
85 .byte 0
86
87
88 # Kernel attributes; used by setup
89
90 .org 497
91 setup_sects: .byte SETUPSECTS
92 root_flags: .word ROOT_RDONLY
93 syssize: .word SYSSIZE
94 swap_dev: .word SWAP_DEV
95 ram_size: .word RAMDISK
96 vid_mode: .word SVGA_MODE
97 root_dev: .word ROOT_DEV
98 boot_flag: .word 0xAA55
99
下面这个头文件boot.h

1 #ifndef _LINUX_BOOT_H
2 #define _LINUX_BOOT_H
3
4 /* Don't touch these, unless you really know what you're doing. */
5 #define DEF_INITSEG 0x9000
6 #define DEF_SYSSEG 0x1000
7 #define DEF_SETUPSEG 0x9020
8 #define DEF_SYSSIZE 0x7F00
9
10 /* Internal svga startup constants */
11 #define NORMAL_VGA 0xffff /* 80x25 mode */
12 #define EXTENDED_VGA 0xfffe /* 80x50 mode */
13 #define ASK_VGA 0xfffd /* ask for it at bootup */
14
15 #endif
16
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: