]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/boot/i386/gptboot/gptldr.S
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / boot / i386 / gptboot / gptldr.S
1 /*-
2  * Copyright (c) 2007 Yahoo!, Inc.
3  * All rights reserved.
4  * Written by: John Baldwin <jhb@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the author nor the names of any co-contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  *
32  * Partly from: src/sys/boot/i386/boot2/boot1.S 1.31
33  */
34
35 /* Memory Locations */
36                 .set MEM_REL,0x700              # Relocation address
37                 .set MEM_ARG,0x900              # Arguments
38                 .set MEM_ORG,0x7c00             # Origin
39                 .set MEM_BUF,0x8cec             # Load area
40                 .set MEM_BTX,0x9000             # BTX start
41                 .set MEM_JMP,0x9010             # BTX entry point
42                 .set MEM_USR,0xa000             # Client start
43                 .set BDA_BOOT,0x472             # Boot howto flag
44         
45 /* Misc. Constants */
46                 .set SIZ_PAG,0x1000             # Page size
47                 .set SIZ_SEC,0x200              # Sector size
48                 .set COPY_BLKS,0x4              # Number of blocks
49                                                 # to copy for boot2
50                 .set COPY_BLK_SZ,0x8000         # Copy in 32k blocks; must be
51                                                 # a multiple of 16 bytes
52
53                 .globl start
54                 .code16
55
56 /*
57  * Copy BTX and boot2 to the right locations and start it all up.
58  */
59
60 /*
61  * Setup the segment registers to flat addressing (segment 0) and setup the
62  * stack to end just below the start of our code.
63  */
64 start:          xor %cx,%cx                     # Zero
65                 mov %cx,%es                     # Address
66                 mov %cx,%ds                     #  data
67                 mov %cx,%ss                     # Set up
68                 mov $start,%sp                  #  stack
69
70 /*
71  * BTX is right after us at 'end'.  We read the length of BTX out of
72  * its header to find boot2.  We need to copy boot2 to MEM_USR and BTX
73  * to MEM_BTX.  Since those might overlap, we have to copy boot2
74  * backwards first and then copy BTX.  We aren't sure exactly how long
75  * boot2 is, but it's currently under 128kB so we'll copy 4 blocks of 32kB
76  * each; this can be adjusted via COPY_BLK and COPY_BLK_SZ above.
77  */
78                 mov $end,%bx                    # BTX
79                 mov 0xa(%bx),%si                # Get BTX length and set
80                 add %bx,%si                     #  %si to start of boot2
81                 dec %si                         # Set %ds:%si to point at the
82                 mov %si,%ax                     # last byte we want to copy
83                 shr $4,%ax                      # from boot2, with %si made as
84                 add $(COPY_BLKS*COPY_BLK_SZ/16),%ax     # small as possible.
85                 and $0xf,%si                    # 
86                 mov %ax,%ds                     #
87                 mov $MEM_USR/16,%ax             # Set %es:(-1) to point at
88                 add $(COPY_BLKS*COPY_BLK_SZ/16),%ax     # the last byte we
89                 mov %ax,%es                     # want to copy boot2 into.
90                 mov $COPY_BLKS,%bx              # Copy COPY_BLKS 32k blocks
91 copyloop:
92                 add $COPY_BLK_SZ,%si            # Adjust %ds:%si to point at
93                 mov %ds,%ax                     # the end of the next 32k to
94                 sub $COPY_BLK_SZ/16,%ax         # copy from boot2
95                 mov %ax,%ds
96                 mov $COPY_BLK_SZ-1,%di          # Adjust %es:%di to point at
97                 mov %es,%ax                     # the end of the next 32k into
98                 sub $COPY_BLK_SZ/16,%ax         # which we want boot2 copied
99                 mov %ax,%es
100                 mov $COPY_BLK_SZ,%cx            # Copy 32k
101                 std
102                 rep movsb
103                 dec %bx
104                 jnz copyloop
105                 mov %cx,%ds                     # Reset %ds and %es
106                 mov %cx,%es
107                 mov $end,%bx                    # BTX
108                 mov 0xa(%bx),%cx                # Get BTX length and set
109                 mov %bx,%si                     #  %si to end of BTX
110                 mov $MEM_BTX,%di                # %di -> end of BTX at
111                 add %cx,%si                     #  MEM_BTX
112                 add %cx,%di
113                 dec %si
114                 dec %di
115                 rep movsb                       # Move BTX
116                 cld                             # String ops inc
117 /*
118  * Enable A20 so we can access memory above 1 meg.
119  * Use the zero-valued %cx as a timeout for embedded hardware which do not
120  * have a keyboard controller.
121  */
122 seta20:         cli                             # Disable interrupts
123 seta20.1:       dec %cx                         # Timeout?
124                 jz seta20.3                     # Yes
125                 inb $0x64,%al                   # Get status
126                 testb $0x2,%al                  # Busy?
127                 jnz seta20.1                    # Yes
128                 movb $0xd1,%al                  # Command: Write
129                 outb %al,$0x64                  #  output port
130 seta20.2:       inb $0x64,%al                   # Get status
131                 testb $0x2,%al                  # Busy?
132                 jnz seta20.2                    # Yes
133                 movb $0xdf,%al                  # Enable
134                 outb %al,$0x60                  #  A20
135 seta20.3:       sti                             # Enable interrupts
136
137 /*
138  * Save drive number from BIOS so boot2 can see it and start BTX.
139  */
140                 movb %dl,MEM_ARG
141                 jmp MEM_JMP                     # Start BTX
142 end: