@@ -247,9 +247,10 @@ xen/arch/arm/xen.lds
xen/arch/x86/asm-offsets.s
xen/arch/x86/boot/mkelf32
xen/arch/x86/xen.lds
+xen/arch/x86/boot/cmdline.S
xen/arch/x86/boot/reloc.S
-xen/arch/x86/boot/reloc.bin
-xen/arch/x86/boot/reloc.lnk
+xen/arch/x86/boot/*.bin
+xen/arch/x86/boot/*.lnk
xen/arch/x86/efi.lds
xen/arch/x86/efi/check.efi
xen/arch/x86/efi/disabled
@@ -220,5 +220,5 @@ clean::
rm -f asm-offsets.s *.lds boot/*.o boot/*~ boot/core boot/mkelf32
rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d
rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.efi efi/disabled efi/mkreloc
- rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
+ rm -f boot/cmdline.S boot/reloc.S boot/*.lnk boot/*.bin
rm -f note.o
@@ -1,9 +1,16 @@
obj-bin-y += head.o
-RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
+DEFS_H_DEPS = defs.h $(BASEDIR)/include/xen/stdbool.h
+
+CMDLINE_DEPS = $(DEFS_H_DEPS) video.h
+
+RELOC_DEPS = $(DEFS_H_DEPS) $(BASEDIR)/include/xen/multiboot.h \
$(BASEDIR)/include/xen/multiboot2.h
-head.o: reloc.S
+head.o: cmdline.S reloc.S
+
+cmdline.S: cmdline.c $(CMDLINE_DEPS)
+ $(MAKE) -f build32.mk $@ CMDLINE_DEPS="$(CMDLINE_DEPS)"
reloc.S: reloc.c $(RELOC_DEPS)
$(MAKE) -f build32.mk $@ RELOC_DEPS="$(RELOC_DEPS)"
@@ -32,6 +32,8 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
%.o: %.c
$(CC) $(CFLAGS) -c -fpic $< -o $@
+cmdline.o: cmdline.c $(CMDLINE_DEPS)
+
reloc.o: reloc.c $(RELOC_DEPS)
.PRECIOUS: %.bin %.lnk
deleted file mode 100644
@@ -1,367 +0,0 @@
-/******************************************************************************
- * cmdline.S
- *
- * Early command-line parsing.
- */
-
- .code32
-
-#include "video.h"
-
-# NB. String pointer on stack is modified to point past parsed digits.
-.Latoi:
- push %ebx
- push %ecx
- push %edx
- push %esi
- xor %ebx,%ebx /* %ebx = accumulator */
- mov $10,%ecx /* %ecx = base (default base 10) */
- mov 16+4(%esp),%esi /* %esi = pointer into ascii string. */
- lodsb
- cmpb $'0',%al
- jne 2f
- mov $8,%ecx /* Prefix '0' => octal (base 8) */
- lodsb
- cmpb $'x',%al
- jne 2f
- mov $16,%ecx /* Prefix '0x' => hex (base 16) */
-1: lodsb
-2: sub $'0',%al
- jb 4f
- cmp $9,%al
- jbe 3f
- sub $'A'-'0'-10,%al
- jb 4f
- cmp $15,%al
- jbe 3f
- sub $'a'-'A',%al
- jb 4f
-3: cmp %cl,%al
- jae 4f
- movzbl %al,%eax
- xchg %eax,%ebx
- mul %ecx
- xchg %eax,%ebx
- add %eax,%ebx
- jmp 1b
-4: mov %ebx,%eax
- dec %esi
- mov %esi,16+4(%esp)
- pop %esi
- pop %edx
- pop %ecx
- pop %ebx
- ret
-
-.Lstrstr:
- push %ecx
- push %edx
- push %esi
- push %edi
- xor %eax,%eax
- xor %ecx,%ecx
- not %ecx
- mov 16+4(%esp),%esi
- mov 16+8(%esp),%edi
- repne scasb
- not %ecx
- dec %ecx
- mov %ecx,%edx
-1: mov 16+8(%esp),%edi
- mov %esi,%eax
- mov %edx,%ecx
- repe cmpsb
- je 2f
- xchg %eax,%esi
- inc %esi
- cmpb $0,-1(%eax)
- jne 1b
- xor %eax,%eax
-2: pop %edi
- pop %esi
- pop %edx
- pop %ecx
- ret
-
-.Lstr_prefix:
- push %esi
- push %edi
- mov 8+4(%esp),%esi /* 1st arg is prefix string */
- mov 8+8(%esp),%edi /* 2nd arg is main string */
-1: lodsb
- test %al,%al
- jz 2f
- scasb
- je 1b
- sbb %eax,%eax
- or $1,%al
- jmp 3f
-2: xor %eax,%eax
-3: pop %edi
- pop %esi
- ret
-
-.Lstrlen:
- push %ecx
- push %esi
- push %edi
- xor %eax,%eax
- xor %ecx,%ecx
- not %ecx
- mov 12+4(%esp),%edi
- repne scasb
- not %ecx
- dec %ecx
- mov %ecx,%eax
- pop %edi
- pop %esi
- pop %ecx
- ret
-
-.Lfind_option:
- mov 4(%esp),%eax
- dec %eax
- push %ebx
-1: pushl 4+8(%esp)
- inc %eax
- push %eax
- call .Lstrstr
- add $8,%esp
- test %eax,%eax
- jz 3f
- cmp %eax,4+4(%esp)
- je 2f
- cmpb $' ',-1(%eax)
- jne 1b
-2: mov %eax,%ebx
- pushl 4+8(%esp)
- call .Lstrlen
- add $4,%esp
- xadd %eax,%ebx
- /* NUL check (as $'\0' == 0x30 in GAS) */
- cmpb $0,(%ebx)
- je 3f
- cmpb $' ',(%ebx)
- je 3f
- cmpb $'=',(%ebx)
- jne 1b
-3: pop %ebx
- ret
-
-cmdline_parse_early:
- pusha
-
- /* Bail if there is no command line to parse. */
- mov sym_phys(multiboot_ptr),%ebx
- mov MB_flags(%ebx),%eax
- test $4,%al
- jz .Lcmdline_exit
- mov MB_cmdline(%ebx),%eax
- test %eax,%eax
- jz .Lcmdline_exit
-
- /* Check for 'no-real-mode' command-line option. */
- pushl $sym_phys(.Lno_rm_opt)
- pushl MB_cmdline(%ebx)
- call .Lfind_option
- test %eax,%eax
- setnz %al
- or %al,sym_phys(skip_realmode)
-
- /* Check for 'tboot=' command-line option. */
- movl $sym_phys(.Ltboot_opt),4(%esp)
- call .Lfind_option
- test %eax,%eax
- setnz %al
- or %al,sym_phys(skip_realmode) /* tboot= implies no-real-mode */
-
-.Lparse_edd:
- /* Check for 'edd=' command-line option. */
- movl $sym_phys(.Ledd_opt),4(%esp)
- call .Lfind_option
- test %eax,%eax
- jz .Lparse_edid
- cmpb $'=',3(%eax)
- jne .Lparse_edid
- add $4,%eax
- movb $2,sym_phys(opt_edd) /* opt_edd=2: edd=off */
- cmpw $0x666f,(%eax) /* 0x666f == "of" */
- je .Lparse_edid
- decb sym_phys(opt_edd) /* opt_edd=1: edd=skipmbr */
- cmpw $0x6b73,(%eax) /* 0x6b73 == "sk" */
- je .Lparse_edid
- decb sym_phys(opt_edd) /* opt_edd=0: edd=on (default) */
-
-.Lparse_edid:
- /* Check for 'edid=' command-line option. */
- movl $sym_phys(.Ledid_opt),4(%esp)
- call .Lfind_option
- test %eax,%eax
- jz .Lparse_vga
- cmpb $'=',4(%eax)
- jne .Lparse_vga
- add $5,%eax
- mov %eax,%ebx
- push %ebx
- pushl $sym_phys(.Ledid_force)
- call .Lstr_prefix
- add $8,%esp
- movb $2,sym_phys(opt_edid) /* opt_edid=2: edid=force */
- test %eax,%eax
- jz .Lparse_vga
- push %ebx
- pushl $sym_phys(.Ledid_no)
- call .Lstr_prefix
- add $8,%esp
- decb sym_phys(opt_edid) /* opt_edid=1: edid=no */
- test %eax,%eax
- jz .Lparse_vga
- decb sym_phys(opt_edid) /* opt_edid=0: default */
-
-.Lparse_vga:
- /* Check for 'vga=' command-line option. */
- movl $sym_phys(.Lvga_opt),4(%esp)
- call .Lfind_option
- add $8,%esp
- test %eax,%eax
- jz .Lcmdline_exit
- cmpb $'=',3(%eax)
- jne .Lcmdline_exit
- add $4,%eax
-
- /* Found the 'vga=' option. Default option is to display vga menu. */
- movw $ASK_VGA,sym_phys(boot_vid_mode)
-
- /* Check for 'vga=text-80x<rows>. */
- mov %eax,%ebx
- push %ebx
- pushl $sym_phys(.Lvga_text80)
- call .Lstr_prefix
- add $8,%esp
- test %eax,%eax
- jnz .Lparse_vga_gfx
-
- /* We have 'vga=text-80x<rows>'. */
- add $8,%ebx
- push %ebx
- call .Latoi
- add $4,%esp
- mov %ax,%bx
- lea sym_phys(.Lvga_text_modes),%esi
-1: lodsw
- test %ax,%ax
- jz .Lcmdline_exit
- cmp %ax,%bx
- lodsw
- jne 1b
- mov %ax,sym_phys(boot_vid_mode)
- jmp .Lcmdline_exit
-
-.Lparse_vga_gfx:
- /* Check for 'vga=gfx-<width>x<height>x<depth>'. */
- push %ebx
- pushl $sym_phys(.Lvga_gfx)
- call .Lstr_prefix
- add $8,%esp
- test %eax,%eax
- jnz .Lparse_vga_mode
-
- /* We have 'vga=gfx-<width>x<height>x<depth>'. */
- /* skip 'gfx-' */
- add $4,%ebx
- /* parse <width> */
- push %ebx
- call .Latoi
- pop %esi
- mov %ax,sym_phys(vesa_size)+0
- /* skip 'x' */
- lodsb
- cmpb $'x',%al
- jne .Lcmdline_exit
- /* parse <height> */
- push %esi
- call .Latoi
- pop %esi
- mov %ax,sym_phys(vesa_size)+2
- /* skip 'x' */
- lodsb
- cmpb $'x',%al
- jne .Lcmdline_exit
- /* parse <depth> */
- push %esi
- call .Latoi
- pop %esi
- mov %ax,sym_phys(vesa_size)+4
- /* commit to vesa mode */
- movw $VIDEO_VESA_BY_SIZE,sym_phys(boot_vid_mode)
- jmp .Lcmdline_exit
-
-.Lparse_vga_mode:
- /* Check for 'vga=mode-<mode>'. */
- push %ebx
- pushl $sym_phys(.Lvga_mode)
- call .Lstr_prefix
- add $8,%esp
- test %eax,%eax
- jnz .Lparse_vga_current
-
- /* We have 'vga=mode-<mode>'. */
- add $5,%ebx
- push %ebx
- call .Latoi
- add $4,%esp
- mov %ax,sym_phys(boot_vid_mode)
- jmp .Lcmdline_exit
-
-.Lparse_vga_current:
- /* Check for 'vga=current'. */
- push %ebx
- pushl $sym_phys(.Lvga_current)
- call .Lstr_prefix
- add $8,%esp
- test %eax,%eax
- jnz .Lcmdline_exit
-
- /* We have 'vga=current'. */
- movw $VIDEO_CURRENT_MODE,sym_phys(boot_vid_mode)
-
-.Lcmdline_exit:
- popa
- ret
-
- .pushsection .init.rodata, "a", @progbits
-
-.Lvga_text_modes: /* rows, mode_number */
- .word 25,VIDEO_80x25
- .word 50,VIDEO_80x50
- .word 43,VIDEO_80x43
- .word 28,VIDEO_80x28
- .word 30,VIDEO_80x30
- .word 34,VIDEO_80x34
- .word 60,VIDEO_80x60
- .word 0
-
-.Lvga_opt:
- .asciz "vga"
-.Lvga_text80:
- .asciz "text-80x"
-.Lvga_gfx:
- .asciz "gfx-"
-.Lvga_mode:
- .asciz "mode-"
-.Lvga_current:
- .asciz "current"
-.Lno_rm_opt:
- .asciz "no-real-mode"
-.Ltboot_opt:
- .asciz "tboot"
-.Ledid_opt:
- .asciz "edid"
-.Ledid_force:
- .asciz "force"
-.Ledid_no:
- .asciz "no"
-.Ledd_opt:
- .asciz "edd"
-
- .popsection
new file mode 100644
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * strlen(), strncmp(), strchr(), strspn() and strcspn() were copied from
+ * Linux kernel source (linux/lib/string.c).
+ */
+
+/*
+ * This entry point is entered from xen/arch/x86/boot/head.S with:
+ * - 0x4(%esp) = &cmdline,
+ * - 0x8(%esp) = &early_boot_opts.
+ */
+asm (
+ " .text \n"
+ " .globl _start \n"
+ "_start: \n"
+ " jmp cmdline_parse_early \n"
+ );
+
+#include "defs.h"
+#include "video.h"
+
+/* Keep in sync with trampoline.S:early_boot_opts label! */
+typedef struct __packed {
+ u8 skip_realmode;
+ u8 opt_edd;
+ u8 opt_edid;
+ u8 padding;
+ u16 boot_vid_mode;
+ u16 vesa_width;
+ u16 vesa_height;
+ u16 vesa_depth;
+} early_boot_opts_t;
+
+/*
+ * Space and TAB are obvious delimiters. However, I am
+ * adding "\n" and "\r" here too. Just in case when
+ * crazy bootloader/user puts them somewhere.
+ */
+static const char delim_chars_comma[] = ", \n\r\t";
+
+#define delim_chars (delim_chars_comma + 1)
+
+static size_t strlen(const char *s)
+{
+ const char *sc;
+
+ for ( sc = s; *sc != '\0'; ++sc )
+ /* nothing */;
+ return sc - s;
+}
+
+static int strncmp(const char *cs, const char *ct, size_t count)
+{
+ unsigned char c1, c2;
+
+ while ( count )
+ {
+ c1 = *cs++;
+ c2 = *ct++;
+ if ( c1 != c2 )
+ return c1 < c2 ? -1 : 1;
+ if ( !c1 )
+ break;
+ count--;
+ }
+ return 0;
+}
+
+static char *strchr(const char *s, int c)
+{
+ for ( ; *s != (char)c; ++s )
+ if ( *s == '\0' )
+ return NULL;
+ return (char *)s;
+}
+
+static size_t strspn(const char *s, const char *accept)
+{
+ const char *p;
+ const char *a;
+ size_t count = 0;
+
+ for ( p = s; *p != '\0'; ++p )
+ {
+ for ( a = accept; *a != '\0'; ++a )
+ {
+ if ( *p == *a )
+ break;
+ }
+ if ( *a == '\0' )
+ return count;
+ ++count;
+ }
+ return count;
+}
+
+static size_t strcspn(const char *s, const char *reject)
+{
+ const char *p;
+ const char *r;
+ size_t count = 0;
+
+ for ( p = s; *p != '\0'; ++p )
+ {
+ for ( r = reject; *r != '\0'; ++r )
+ {
+ if ( *p == *r )
+ return count;
+ }
+ ++count;
+ }
+ return count;
+}
+
+static unsigned int strtoui(const char *s, const char *stop, const char **next)
+{
+ char base = 10, l;
+ unsigned long long res = 0;
+
+ if ( *s == '0' )
+ base = (tolower(*++s) == 'x') ? (++s, 16) : 8;
+
+ for ( ; *s != '\0'; ++s )
+ {
+ if ( stop && strchr(stop, *s) )
+ goto out;
+
+ if ( *s < '0' || (*s > '7' && base == 8) )
+ {
+ res = UINT_MAX;
+ goto out;
+ }
+
+ l = tolower(*s);
+
+ if ( *s > '9' && (base != 16 || l < 'a' || l > 'f') )
+ {
+ res = UINT_MAX;
+ goto out;
+ }
+
+ res *= base;
+ res += (l >= 'a') ? (l - 'a' + 10) : (*s - '0');
+
+ if ( res >= UINT_MAX )
+ {
+ res = UINT_MAX;
+ goto out;
+ }
+ }
+
+ out:
+ if ( next )
+ *next = s;
+
+ return res;
+}
+
+static int strmaxcmp(const char *cs, const char *ct, const char *_delim_chars)
+{
+ return strncmp(cs, ct, max(strcspn(cs, _delim_chars), strlen(ct)));
+}
+
+static int strsubcmp(const char *cs, const char *ct)
+{
+ return strncmp(cs, ct, strlen(ct));
+}
+
+static const char *find_opt(const char *cmdline, const char *opt, bool arg)
+{
+ size_t lc, lo;
+
+ lo = strlen(opt);
+
+ for ( ; ; )
+ {
+ cmdline += strspn(cmdline, delim_chars);
+
+ if ( *cmdline == '\0' )
+ return NULL;
+
+ if ( !strmaxcmp(cmdline, "--", delim_chars) )
+ return NULL;
+
+ lc = strcspn(cmdline, delim_chars);
+
+ if ( !strncmp(cmdline, opt, arg ? lo : max(lc, lo)) )
+ return cmdline + lo;
+
+ cmdline += lc;
+ }
+}
+
+static bool skip_realmode(const char *cmdline)
+{
+ return find_opt(cmdline, "no-real-mode", false) || find_opt(cmdline, "tboot=", true);
+}
+
+static u8 edd_parse(const char *cmdline)
+{
+ const char *c;
+
+ c = find_opt(cmdline, "edd=", true);
+
+ if ( !c )
+ return 0;
+
+ if ( !strmaxcmp(c, "off", delim_chars) )
+ return 2;
+
+ return !strmaxcmp(c, "skipmbr", delim_chars);
+}
+
+static u8 edid_parse(const char *cmdline)
+{
+ const char *c;
+
+ c = find_opt(cmdline, "edid=", true);
+
+ if ( !c )
+ return 0;
+
+ if ( !strmaxcmp(c, "force", delim_chars) )
+ return 2;
+
+ return !strmaxcmp(c, "no", delim_chars);
+}
+
+static u16 rows2vmode(unsigned int rows)
+{
+ switch ( rows )
+ {
+ case 25:
+ return VIDEO_80x25;
+
+ case 28:
+ return VIDEO_80x28;
+
+ case 30:
+ return VIDEO_80x30;
+
+ case 34:
+ return VIDEO_80x34;
+
+ case 43:
+ return VIDEO_80x43;
+
+ case 50:
+ return VIDEO_80x50;
+
+ case 60:
+ return VIDEO_80x60;
+
+ default:
+ return ASK_VGA;
+ }
+}
+
+static void vga_parse(const char *cmdline, early_boot_opts_t *ebo)
+{
+ const char *c;
+ unsigned int tmp, vesa_depth, vesa_height, vesa_width;
+
+ c = find_opt(cmdline, "vga=", true);
+
+ if ( !c )
+ return;
+
+ ebo->boot_vid_mode = ASK_VGA;
+
+ if ( !strmaxcmp(c, "current", delim_chars_comma) )
+ ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
+ else if ( !strsubcmp(c, "text-80x") )
+ {
+ c += strlen("text-80x");
+ ebo->boot_vid_mode = rows2vmode(strtoui(c, delim_chars_comma, NULL));
+ }
+ else if ( !strsubcmp(c, "gfx-") )
+ {
+ vesa_width = strtoui(c + strlen("gfx-"), "x", &c);
+
+ if ( vesa_width > U16_MAX )
+ return;
+
+ /*
+ * Increment c outside of strtoui() because otherwise some
+ * compiler may complain with following message:
+ * warning: operation on 'c' may be undefined.
+ */
+ ++c;
+ vesa_height = strtoui(c, "x", &c);
+
+ if ( vesa_height > U16_MAX )
+ return;
+
+ vesa_depth = strtoui(++c, delim_chars_comma, NULL);
+
+ if ( vesa_depth > U16_MAX )
+ return;
+
+ ebo->vesa_width = vesa_width;
+ ebo->vesa_height = vesa_height;
+ ebo->vesa_depth = vesa_depth;
+ ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;
+ }
+ else if ( !strsubcmp(c, "mode-") )
+ {
+ tmp = strtoui(c + strlen("mode-"), delim_chars_comma, NULL);
+
+ if ( tmp > U16_MAX )
+ return;
+
+ ebo->boot_vid_mode = tmp;
+ }
+}
+
+void __stdcall cmdline_parse_early(const char *cmdline, early_boot_opts_t *ebo)
+{
+ if ( !cmdline )
+ return;
+
+ ebo->skip_realmode = skip_realmode(cmdline);
+ ebo->opt_edd = edd_parse(cmdline);
+ ebo->opt_edid = edid_parse(cmdline);
+ vga_parse(cmdline, ebo);
+}
new file mode 100644
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * max() was copied from xen/xen/include/xen/kernel.h.
+ */
+
+#ifndef __BOOT_DEFS_H__
+#define __BOOT_DEFS_H__
+
+#include "../../../include/xen/stdbool.h"
+
+#define __packed __attribute__((__packed__))
+#define __stdcall __attribute__((__stdcall__))
+
+#define NULL ((void *)0)
+
+#define ALIGN_UP(arg, align) \
+ (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))
+
+#define min(x,y) ({ \
+ const typeof(x) _x = (x); \
+ const typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+ const typeof(x) _x = (x); \
+ const typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x > _y ? _x : _y; })
+
+#define _p(val) ((void *)(unsigned long)(val))
+
+#define tolower(c) ((c) | 0x20)
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef unsigned int size_t;
+
+#define U16_MAX ((u16)(~0U))
+#define UINT_MAX (~0U)
+
+#endif /* __BOOT_DEFS_H__ */
@@ -142,9 +142,6 @@ edd_next:
edd_done:
ret
-opt_edd:
- .byte 0 # edd=on/off/skipmbr
-
GLOBAL(boot_edd_info_nr)
.byte 0
GLOBAL(boot_mbr_signature_nr)
@@ -511,6 +511,13 @@ trampoline_setup:
cmpb $0,sym_phys(skip_realmode)
jnz 1f
+ /* Bail if there is no command line to parse. */
+ mov sym_phys(multiboot_ptr),%ebx
+ testl $MBI_CMDLINE,MB_flags(%ebx)
+ jz 1f
+
+ pushl $sym_phys(early_boot_opts)
+ pushl MB_cmdline(%ebx)
call cmdline_parse_early
1:
@@ -529,6 +536,7 @@ trampoline_setup:
/* Jump into the relocated trampoline. */
lret
+cmdline_parse_early:
#include "cmdline.S"
reloc:
@@ -25,21 +25,10 @@ asm (
" jmp reloc \n"
);
-typedef unsigned int u32;
-typedef unsigned long long u64;
-
+#include "defs.h"
#include "../../../include/xen/multiboot.h"
#include "../../../include/xen/multiboot2.h"
-#define NULL ((void *)0)
-
-#define __stdcall __attribute__((__stdcall__))
-
-#define ALIGN_UP(arg, align) \
- (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))
-
-#define _p(val) ((void *)(unsigned long)(val))
-
#define get_mb2_data(tag, type, member) (((multiboot2_tag_##type##_t *)(tag))->member)
#define get_mb2_string(tag, type, member) ((u32)get_mb2_data(tag, type, member))
@@ -220,8 +220,23 @@ trampoline_boot_cpu_entry:
/* Jump to the common bootstrap entry point. */
jmp trampoline_protmode_entry
+#include "video.h"
+
+ .align 2
+/* Keep in sync with cmdline.c:early_boot_opts_t type! */
+early_boot_opts:
skip_realmode:
.byte 0
+opt_edd:
+ .byte 0 /* edd=on/off/skipmbr */
+opt_edid:
+ .byte 0 /* EDID parsing option (force/no/default). */
+/* Padding. */
+ .byte 0
+GLOBAL(boot_vid_mode)
+ .word VIDEO_80x25 /* If we don't run at all, assume basic video mode 3 at 80x25. */
+vesa_size:
+ .word 0,0,0 /* width x depth x height */
GLOBAL(kbd_shift_flags)
.byte 0
@@ -945,7 +945,6 @@ store_edid:
#endif
ret
-opt_edid: .byte 0 # EDID parsing option (force/no/default)
mt_end: .word 0 # End of video mode table if built
edit_buf: .space 6 # Line editor buffer
card_name: .word 0 # Pointer to adapter name
@@ -991,12 +990,6 @@ name_bann: .asciz "Video adapter: "
force_size: .word 0 # Use this size instead of the one in BIOS vars
-vesa_size: .word 0,0,0 # width x depth x height
-
-/* If we don't run at all, assume basic video mode 3 at 80x25. */
- .align 2
-GLOBAL(boot_vid_mode)
- .word VIDEO_80x25
GLOBAL(boot_vid_info)
.byte 0, 0 /* orig_x, orig_y */
.byte 3 /* text mode 3 */