]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/boot/i386/gptboot/gptldr.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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
49                 .globl start
50                 .code16
51
52 /*
53  * Copy BTX and boot2 to the right locations and start it all up.
54  */
55
56 /*
57  * Setup the segment registers to flat addressing (segment 0) and setup the
58  * stack to end just below the start of our code.
59  */
60 start:          xor %cx,%cx                     # Zero
61                 mov %cx,%es                     # Address
62                 mov %cx,%ds                     #  data
63                 mov %cx,%ss                     # Set up
64                 mov $start,%sp                  #  stack
65
66 /*
67  * BTX is right after us at 'end'.  We read the length of BTX out of
68  * its header to find boot2.  We need to copy boot2 to MEM_USR and BTX
69  * to MEM_BTX.  Since those might overlap, we have to copy boot2
70  * backwards first and then copy BTX.  We aren't sure exactly how long
71  * boot2 is, but we assume it can't be longer than 64k, so we just always
72  * copy 64k.
73  */
74                 mov $end,%bx                    # BTX
75                 mov 0xa(%bx),%si                # Get BTX length and set
76                 add %bx,%si                     #  %si to start of boot2
77                 mov %si,%ax                     # Align %ds:%si on a
78                 shr $4,%ax                      #  paragraph boundary
79                 and $0xf,%si                    #  with the smallest
80                 mov %ax,%ds                     #  possible %si
81                 add $(64 * 1024 - 16),%si
82                 mov $MEM_USR/16,%ax             # Point %es:%di at end of
83                 mov $(64 * 1024 - 16),%di       #  largest boot2 range
84                 mov %ax,%es
85                 std
86                 mov %di,%cx                     # Copy 64k - paragraph + 1 
87                 inc %cx                         #  bytes
88                 rep movsb
89                 mov %cx,%ds                     # Reset %ds and %es
90                 mov %cx,%es
91                 mov 0xa(%bx),%cx                # Get BTX length and set
92                 mov %bx,%si                     #  %si to end of BTX
93                 mov $MEM_BTX,%di                # %di -> end of BTX at
94                 add %cx,%si                     #  MEM_BTX
95                 add %cx,%di
96                 dec %si
97                 dec %di
98                 rep movsb                       # Move BTX
99                 cld                             # String ops inc
100 /*
101  * Enable A20 so we can access memory above 1 meg.
102  * Use the zero-valued %cx as a timeout for embedded hardware which do not
103  * have a keyboard controller.
104  */
105 seta20:         cli                             # Disable interrupts
106 seta20.1:       dec %cx                         # Timeout?
107                 jz seta20.3                     # Yes
108                 inb $0x64,%al                   # Get status
109                 testb $0x2,%al                  # Busy?
110                 jnz seta20.1                    # Yes
111                 movb $0xd1,%al                  # Command: Write
112                 outb %al,$0x64                  #  output port
113 seta20.2:       inb $0x64,%al                   # Get status
114                 testb $0x2,%al                  # Busy?
115                 jnz seta20.2                    # Yes
116                 movb $0xdf,%al                  # Enable
117                 outb %al,$0x60                  #  A20
118 seta20.3:       sti                             # Enable interrupts
119
120 /*
121  * Save drive number from BIOS so boot2 can see it and start BTX.
122  */
123                 movb %dl,MEM_ARG
124                 jmp MEM_JMP                     # Start BTX
125 end: