Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / i386 / prefix / lkrnprefix.S
1 FILE_LICENCE ( GPL_ANY )
2
3 #define BZI_LOAD_HIGH_ADDR 0x100000
4
5         .text
6         .arch i386
7         .code16
8         .section ".prefix", "ax", @progbits
9         .globl  _lkrn_start
10 _lkrn_start:
11
12 /*****************************************************************************
13  *
14  * Kernel header
15  *
16  * We place our prefix (i.e. our .prefix and .text16.early sections)
17  * within the bzImage real-mode portion which gets loaded at
18  * 1000:0000, and our payload (i.e. everything else) within the
19  * bzImage protected-mode portion which gets loaded at 0x100000
20  * upwards.
21  *
22  */
23
24         .org    0x1f1
25 setup_sects:
26         .byte   -1 /* Allow for initial "boot sector" */
27         .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
28         .ascii  "ADHL"
29         .long   setup_sects
30         .long   512
31         .long   0
32         .previous
33 root_flags:
34         .word   0
35 syssize:
36         .long   0
37         .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
38         .ascii  "ADPL"
39         .long   syssize
40         .long   16
41         .long   0
42         .previous
43 ram_size:
44         .word   0
45 vid_mode:
46         .word   0
47 root_dev:
48         .word   0
49 boot_flag:
50         .word   0xaa55
51 jump:
52         /* Manually specify a two-byte jmp instruction here rather
53          * than leaving it up to the assembler.
54          */
55         .byte   0xeb, ( setup - header )
56 header:
57         .byte   'H', 'd', 'r', 'S'
58 version:
59         .word   0x0207 /* 2.07 */
60 realmode_swtch:
61         .long   0
62 start_sys:
63         .word   0
64 kernel_version:
65         .word   version_string - 0x200
66 type_of_loader:
67         .byte   0
68 loadflags:
69         .byte   0x01 /* LOADED_HIGH */
70 setup_move_size:
71         .word   0
72 code32_start:
73         .long   0
74 ramdisk_image:
75         .long   0
76 ramdisk_size:
77         .long   0
78 bootsect_kludge:
79         .long   0
80 heap_end_ptr:
81         .word   0
82 ext_loader_ver:
83         .byte   0
84 ext_loader_type:
85         .byte   0
86 cmd_line_ptr:
87         .long   0
88 initrd_addr_max:
89         .long   0xffffffff
90 kernel_alignment:
91         .long   0
92 relocatable_kernel:
93         .byte   0
94 min_alignment:
95         .byte   0
96 xloadflags:
97         .word   0
98 cmdline_size:
99         .long   0x7ff
100 hardware_subarch:
101         .long   0
102 hardware_subarch_data:
103         .byte   0, 0, 0, 0, 0, 0, 0, 0
104
105 version_string:
106         .asciz  VERSION
107
108 /*****************************************************************************
109  *
110  * Setup code
111  *
112  */
113
114 setup:
115         /* Fix up code segment */
116         pushw   %ds
117         pushw   $1f
118         lret
119 1:
120         /* Set up stack just below 0x7c00 and clear direction flag */
121         xorw    %ax, %ax
122         movw    %ax, %ss
123         movw    $0x7c00, %sp
124         cld
125
126         /* Retrieve command-line pointer */
127         movl    cmd_line_ptr, %edx
128         testl   %edx, %edx
129         jz      no_cmd_line
130
131         /* Set up %es:%di to point to command line */
132         movl    %edx, %edi
133         andl    $0xf, %edi
134         rorl    $4, %edx
135         movw    %dx, %es
136
137         /* Find length of command line */
138         pushw   %di
139         movw    $0xffff, %cx
140         repnz scasb
141         notw    %cx
142         popw    %si
143
144         /* Make space for command line on stack */
145         movw    %sp, %di
146         subw    %cx, %di
147         andw    $~0xf, %di
148         movw    %di, %sp
149
150         /* Copy command line to stack */
151         pushw   %ds
152         pushw   %es
153         popw    %ds
154         pushw   %ss
155         popw    %es
156         rep movsb
157         popw    %ds
158
159         /* Store new command-line pointer */
160         movzwl  %sp, %edx
161 no_cmd_line:
162
163         /* Calculate maximum relocation address */
164         movl    ramdisk_image, %ebp
165         testl   %ebp, %ebp
166         jnz     1f
167         orl     $0xffffffff, %ebp /* Allow arbitrary relocation if no initrd */
168 1:
169         /* Install iPXE */
170         call    alloc_basemem
171         xorl    %esi, %esi
172         xorl    %edi, %edi
173         call    install_prealloc
174
175         /* Set up real-mode stack */
176         movw    %bx, %ss
177         movw    $_estack16, %sp
178
179         /* Jump to .text16 segment */
180         pushw   %ax
181         pushw   $1f
182         lret
183         .section ".text16", "awx", @progbits
184 1:
185         /* Retrieve initrd pointer and size */
186         movl    ramdisk_image, %ebp
187         movl    ramdisk_size, %ecx
188
189         /* Set up %ds for access to .data16 */
190         movw    %bx, %ds
191
192         /* Store command-line pointer */
193         movl    %edx, cmdline_phys
194
195         /* Store initrd pointer and size */
196         movl    %ebp, initrd_phys
197         movl    %ecx, initrd_len
198
199         /* Run iPXE */
200         pushl   $main
201         pushw   %cs
202         call    prot_call
203         popl    %ecx /* discard */
204
205         /* Uninstall iPXE */
206         call    uninstall
207
208         /* Boot next device */
209         int $0x18
210
211 /*****************************************************************************
212  *
213  * Open payload (called by libprefix)
214  *
215  * Parameters:
216  *   %ds:0000 : Prefix
217  *   %esi : Buffer for copy of image source (or zero if no buffer available)
218  *   %ecx : Expected offset within buffer of first payload block
219  * Returns:
220  *   %esi : Valid image source address (buffered or unbuffered)
221  *   %ecx : Actual offset within buffer of first payload block
222  *   CF set on error
223  */
224
225         .section ".text16.early", "awx", @progbits
226         .globl  open_payload
227 open_payload:
228
229         /* Our payload will always end up at BZI_LOAD_HIGH_ADDR */
230         movl    $BZI_LOAD_HIGH_ADDR, %esi
231         xorl    %ecx, %ecx
232         lret
233
234         /* Payload must be aligned to a whole number of setup sectors */
235         .globl  _payload_align
236         .equ    _payload_align, 512