boot.asm

  1 obj/boot/boot.out:     file format elf32-i386
  2 
  3 
  4 Disassembly of section .text:
  5 
  6 00007c00 <start>:
  7 .set CR0_PE_ON,      0x1         # protected mode enable flag
  8 
  9 .globl start
 10 start:
 11   .code16                     # Assemble for 16-bit mode
 12   cli                         # Disable interrupts
 13     7c00:    fa                       cli    
 14   cld                         # String operations increment
 15     7c01:    fc                       cld    
 16 
 17   # Set up the important data segment registers (DS, ES, SS).
 18   xorw    %ax,%ax             # Segment number zero
 19     7c02:    31 c0                    xor    %eax,%eax
 20   movw    %ax,%ds             # -> Data Segment
 21     7c04:    8e d8                    mov    %eax,%ds
 22   movw    %ax,%es             # -> Extra Segment
 23     7c06:    8e c0                    mov    %eax,%es
 24   movw    %ax,%ss             # -> Stack Segment
 25     7c08:    8e d0                    mov    %eax,%ss
 26 
 27 00007c0a <seta20.1>:
 28   # Enable A20:
 29   #   For backwards compatibility with the earliest PCs, physical
 30   #   address line 20 is tied low, so that addresses higher than
 31   #   1MB wrap around to zero by default.  This code undoes this.
 32 seta20.1:
 33   inb     $0x64,%al               # Wait for not busy
 34     7c0a:    e4 64                    in     $0x64,%al
 35   testb   $0x2,%al
 36     7c0c:    a8 02                    test   $0x2,%al
 37   jnz     seta20.1
 38     7c0e:    75 fa                    jne    7c0a <seta20.1>
 39 
 40   movb    $0xd1,%al               # 0xd1 -> port 0x64
 41     7c10:    b0 d1                    mov    $0xd1,%al
 42   outb    %al,$0x64
 43     7c12:    e6 64                    out    %al,$0x64
 44 
 45 00007c14 <seta20.2>:
 46 
 47 seta20.2:
 48   inb     $0x64,%al               # Wait for not busy
 49     7c14:    e4 64                    in     $0x64,%al
 50   testb   $0x2,%al
 51     7c16:    a8 02                    test   $0x2,%al
 52   jnz     seta20.2
 53     7c18:    75 fa                    jne    7c14 <seta20.2>
 54 
 55   movb    $0xdf,%al               # 0xdf -> port 0x60
 56     7c1a:    b0 df                    mov    $0xdf,%al
 57   outb    %al,$0x60
 58     7c1c:    e6 60                    out    %al,$0x60
 59 
 60   # Switch from real to protected mode, using a bootstrap GDT
 61   # and segment translation that makes virtual addresses 
 62   # identical to their physical addresses, so that the 
 63   # effective memory map does not change during the switch.
 64   lgdt    gdtdesc
 65     7c1e:    0f 01 16                 lgdtl  (%esi)
 66     7c21:    64 7c 0f                 fs jl  7c33 <protcseg+0x1>
 67   movl    %cr0, %eax
 68     7c24:    20 c0                    and    %al,%al
 69   orl     $CR0_PE_ON, %eax
 70     7c26:    66 83 c8 01              or     $0x1,%ax
 71   movl    %eax, %cr0
 72     7c2a:    0f 22 c0                 mov    %eax,%cr0
 73   
 74   # Jump to next instruction, but in 32-bit code segment.
 75   # Switches processor into 32-bit mode.
 76   ljmp    $PROT_MODE_CSEG, $protcseg
 77     7c2d:    ea                       .byte 0xea
 78     7c2e:    32 7c 08 00              xor    0x0(%eax,%ecx,1),%bh
 79 
 80 00007c32 <protcseg>:
 81 
 82   .code32                     # Assemble for 32-bit mode
 83 protcseg:
 84   # Set up the protected-mode data segment registers
 85   movw    $PROT_MODE_DSEG, %ax    # Our data segment selector
 86     7c32:    66 b8 10 00              mov    $0x10,%ax
 87   movw    %ax, %ds                # -> DS: Data Segment
 88     7c36:    8e d8                    mov    %eax,%ds
 89   movw    %ax, %es                # -> ES: Extra Segment
 90     7c38:    8e c0                    mov    %eax,%es
 91   movw    %ax, %fs                # -> FS
 92     7c3a:    8e e0                    mov    %eax,%fs
 93   movw    %ax, %gs                # -> GS
 94     7c3c:    8e e8                    mov    %eax,%gs
 95   movw    %ax, %ss                # -> SS: Stack Segment
 96     7c3e:    8e d0                    mov    %eax,%ss
 97   
 98   # Set up the stack pointer and call into C.
 99   movl    $start, %esp
100     7c40:    bc 00 7c 00 00           mov    $0x7c00,%esp
101   call bootmain
102     7c45:    e8 cb 00 00 00           call   7d15 <bootmain>
103 
104 00007c4a <spin>:
105 
106   # If bootmain returns (it shouldn't), loop.
107 spin:
108   jmp spin
109     7c4a:    eb fe                    jmp    7c4a <spin>
110 
111 00007c4c <gdt>:
112     ...
113     7c54:    ff                       (bad)  
114     7c55:    ff 00                    incl   (%eax)
115     7c57:    00 00                    add    %al,(%eax)
116     7c59:    9a cf 00 ff ff 00 00     lcall  $0x0,$0xffff00cf
117     7c60:    00                       .byte 0x0
118     7c61:    92                       xchg   %eax,%edx
119     7c62:    cf                       iret   
120     ...
121 
122 00007c64 <gdtdesc>:
123     7c64:    17                       pop    %ss
124     7c65:    00 4c 7c 00              add    %cl,0x0(%esp,%edi,2)
125     ...
126 
127 00007c6a <waitdisk>:
128     }
129 }
130 
131 void
132 waitdisk(void)
133 {
134     7c6a:    55                       push   %ebp
135 
136 static inline uint8_t
137 inb(int port)
138 {
139     uint8_t data;
140     asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
141     7c6b:    ba f7 01 00 00           mov    $0x1f7,%edx
142     7c70:    89 e5                    mov    %esp,%ebp
143     7c72:    ec                       in     (%dx),%al
144     // wait for disk reaady
145     while ((inb(0x1F7) & 0xC0) != 0x40)
146     7c73:    83 e0 c0                 and    $0xffffffc0,%eax
147     7c76:    3c 40                    cmp    $0x40,%al
148     7c78:    75 f8                    jne    7c72 <waitdisk+0x8>
149         /* do nothing */;
150 }
151     7c7a:    5d                       pop    %ebp
152     7c7b:    c3                       ret    
153 
154 00007c7c <readsect>:
155 
156 void
157 readsect(void *dst, uint32_t offset)
158 {
159     7c7c:    55                       push   %ebp
160     7c7d:    89 e5                    mov    %esp,%ebp
161     7c7f:    57                       push   %edi
162     7c80:    8b 4d 0c                 mov    0xc(%ebp),%ecx
163     // wait for disk to be ready
164     waitdisk();
165     7c83:    e8 e2 ff ff ff           call   7c6a <waitdisk>
166 }
167 
168 static inline void
169 outb(int port, uint8_t data)
170 {
171     asm volatile("outb %0,%w1" : : "a" (data), "d" (port));
172     7c88:    b0 01                    mov    $0x1,%al
173     7c8a:    ba f2 01 00 00           mov    $0x1f2,%edx
174     7c8f:    ee                       out    %al,(%dx)
175     7c90:    ba f3 01 00 00           mov    $0x1f3,%edx
176     7c95:    88 c8                    mov    %cl,%al
177     7c97:    ee                       out    %al,(%dx)
178 
179     outb(0x1F2, 1);        // count = 1
180     outb(0x1F3, offset);
181     outb(0x1F4, offset >> 8);
182     7c98:    89 c8                    mov    %ecx,%eax
183     7c9a:    ba f4 01 00 00           mov    $0x1f4,%edx
184     7c9f:    c1 e8 08                 shr    $0x8,%eax
185     7ca2:    ee                       out    %al,(%dx)
186     outb(0x1F5, offset >> 16);
187     7ca3:    89 c8                    mov    %ecx,%eax
188     7ca5:    ba f5 01 00 00           mov    $0x1f5,%edx
189     7caa:    c1 e8 10                 shr    $0x10,%eax
190     7cad:    ee                       out    %al,(%dx)
191     outb(0x1F6, (offset >> 24) | 0xE0);
192     7cae:    89 c8                    mov    %ecx,%eax
193     7cb0:    ba f6 01 00 00           mov    $0x1f6,%edx
194     7cb5:    c1 e8 18                 shr    $0x18,%eax
195     7cb8:    83 c8 e0                 or     $0xffffffe0,%eax
196     7cbb:    ee                       out    %al,(%dx)
197     7cbc:    b0 20                    mov    $0x20,%al
198     7cbe:    ba f7 01 00 00           mov    $0x1f7,%edx
199     7cc3:    ee                       out    %al,(%dx)
200     outb(0x1F7, 0x20);    // cmd 0x20 - read sectors
201 
202     // wait for disk to be ready
203     waitdisk();
204     7cc4:    e8 a1 ff ff ff           call   7c6a <waitdisk>
205     asm volatile("cld\n\trepne\n\tinsl"
206     7cc9:    8b 7d 08                 mov    0x8(%ebp),%edi
207     7ccc:    b9 80 00 00 00           mov    $0x80,%ecx
208     7cd1:    ba f0 01 00 00           mov    $0x1f0,%edx
209     7cd6:    fc                       cld    
210     7cd7:    f2 6d                    repnz insl (%dx),%es:(%edi)
211 
212     // read a sector
213     insl(0x1F0, dst, SECTSIZE/4);
214 }
215     7cd9:    5f                       pop    %edi
216     7cda:    5d                       pop    %ebp
217     7cdb:    c3                       ret    
218 
219 00007cdc <readseg>:
220 {
221     7cdc:    55                       push   %ebp
222     7cdd:    89 e5                    mov    %esp,%ebp
223     7cdf:    57                       push   %edi
224     7ce0:    56                       push   %esi
225     offset = (offset / SECTSIZE) + 1;
226     7ce1:    8b 7d 10                 mov    0x10(%ebp),%edi
227 {
228     7ce4:    53                       push   %ebx
229     end_pa = pa + count;
230     7ce5:    8b 75 0c                 mov    0xc(%ebp),%esi
231 {
232     7ce8:    8b 5d 08                 mov    0x8(%ebp),%ebx
233     offset = (offset / SECTSIZE) + 1;
234     7ceb:    c1 ef 09                 shr    $0x9,%edi
235     end_pa = pa + count;
236     7cee:    01 de                    add    %ebx,%esi
237     offset = (offset / SECTSIZE) + 1;
238     7cf0:    47                       inc    %edi
239     pa &= ~(SECTSIZE - 1);
240     7cf1:    81 e3 00 fe ff ff        and    $0xfffffe00,%ebx
241     while (pa < end_pa) {
242     7cf7:    39 f3                    cmp    %esi,%ebx
243     7cf9:    73 12                    jae    7d0d <readseg+0x31>
244         readsect((uint8_t*) pa, offset);
245     7cfb:    57                       push   %edi
246     7cfc:    53                       push   %ebx
247         offset++;
248     7cfd:    47                       inc    %edi
249         pa += SECTSIZE;
250     7cfe:    81 c3 00 02 00 00        add    $0x200,%ebx
251         readsect((uint8_t*) pa, offset);
252     7d04:    e8 73 ff ff ff           call   7c7c <readsect>
253         offset++;
254     7d09:    58                       pop    %eax
255     7d0a:    5a                       pop    %edx
256     7d0b:    eb ea                    jmp    7cf7 <readseg+0x1b>
257 }
258     7d0d:    8d 65 f4                 lea    -0xc(%ebp),%esp
259     7d10:    5b                       pop    %ebx
260     7d11:    5e                       pop    %esi
261     7d12:    5f                       pop    %edi
262     7d13:    5d                       pop    %ebp
263     7d14:    c3                       ret    
264 
265 00007d15 <bootmain>:
266 {
267     7d15:    55                       push   %ebp
268     7d16:    89 e5                    mov    %esp,%ebp
269     7d18:    56                       push   %esi
270     7d19:    53                       push   %ebx
271     readseg((uint32_t) ELFHDR, SECTSIZE*8, 0);
272     7d1a:    6a 00                    push   $0x0
273     7d1c:    68 00 10 00 00           push   $0x1000
274     7d21:    68 00 00 01 00           push   $0x10000
275     7d26:    e8 b1 ff ff ff           call   7cdc <readseg>
276     if (ELFHDR->e_magic != ELF_MAGIC)
277     7d2b:    83 c4 0c                 add    $0xc,%esp
278     7d2e:    81 3d 00 00 01 00 7f     cmpl   $0x464c457f,0x10000
279     7d35:    45 4c 46 
280     7d38:    75 37                    jne    7d71 <bootmain+0x5c>
281     ph = (struct Proghdr *) ((uint8_t *) ELFHDR + ELFHDR->e_phoff);
282     7d3a:    a1 1c 00 01 00           mov    0x1001c,%eax
283     eph = ph + ELFHDR->e_phnum;
284     7d3f:    0f b7 35 2c 00 01 00     movzwl 0x1002c,%esi
285     ph = (struct Proghdr *) ((uint8_t *) ELFHDR + ELFHDR->e_phoff);
286     7d46:    8d 98 00 00 01 00        lea    0x10000(%eax),%ebx
287     eph = ph + ELFHDR->e_phnum;
288     7d4c:    c1 e6 05                 shl    $0x5,%esi
289     7d4f:    01 de                    add    %ebx,%esi
290     for (; ph < eph; ph++)
291     7d51:    39 f3                    cmp    %esi,%ebx
292     7d53:    73 16                    jae    7d6b <bootmain+0x56>
293         readseg(ph->p_pa, ph->p_memsz, ph->p_offset);
294     7d55:    ff 73 04                 pushl  0x4(%ebx)
295     7d58:    ff 73 14                 pushl  0x14(%ebx)
296     for (; ph < eph; ph++)
297     7d5b:    83 c3 20                 add    $0x20,%ebx
298         readseg(ph->p_pa, ph->p_memsz, ph->p_offset);
299     7d5e:    ff 73 ec                 pushl  -0x14(%ebx)
300     7d61:    e8 76 ff ff ff           call   7cdc <readseg>
301     for (; ph < eph; ph++)
302     7d66:    83 c4 0c                 add    $0xc,%esp
303     7d69:    eb e6                    jmp    7d51 <bootmain+0x3c>
304     ((void (*)(void)) (ELFHDR->e_entry))();
305     7d6b:    ff 15 18 00 01 00        call   *0x10018
306 }
307 
308 static inline void
309 outw(int port, uint16_t data)
310 {
311     asm volatile("outw %0,%w1" : : "a" (data), "d" (port));
312     7d71:    ba 00 8a 00 00           mov    $0x8a00,%edx
313     7d76:    b8 00 8a ff ff           mov    $0xffff8a00,%eax
314     7d7b:    66 ef                    out    %ax,(%dx)
315     7d7d:    b8 00 8e ff ff           mov    $0xffff8e00,%eax
316     7d82:    66 ef                    out    %ax,(%dx)
317     7d84:    eb fe                    jmp    7d84 <bootmain+0x6f>

 

posted @ 2021-11-10 08:59  Pril  阅读(83)  评论(0)    收藏  举报