This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0ed4123326a2121897f3ae5d8b13d227030df1e4
Author: Brennan Ashton <bash...@brennanashton.com>
AuthorDate: Tue Aug 4 03:29:05 2020 -0700

    x86_64: Early framebuffer console
    
    This adds support for creating an early frame buffer and primatives for
    writing to this frame buffer as a console. This does require the font
    infrastructure as well as multiboot2.
    
    Additionally this can now be used with a UEFI bootloader long as it
    boots NuttX via Multiboot2.  There does seem to be a PCI interrupt
    issue when running in UEFI mode.
    
    I was able to boot my laptop using this and see PCI devices enumerate.
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    x86_64: Add conditionals around the multiboot framebuffer
---
 .../x86_64/qemu/boards/qemu-intel64/index.rst      |  19 ++
 arch/x86_64/Kconfig                                |  19 +-
 arch/x86_64/src/common/x86_64_internal.h           |   8 +-
 arch/x86_64/src/intel64/Make.defs                  |   4 +
 arch/x86_64/src/intel64/intel64_head.S             |  14 +-
 arch/x86_64/src/intel64/intel64_lowsetup.c         |  45 +++
 arch/x86_64/src/intel64/intel64_mbfb.c             | 309 +++++++++++++++++++++
 arch/x86_64/src/intel64/intel64_serial.c           |   4 +
 .../intel64/qemu-intel64/configs/earlyfb/defconfig |  72 +++++
 9 files changed, 488 insertions(+), 6 deletions(-)

diff --git a/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst 
b/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
index d1fe76186d..c927ad922a 100644
--- a/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
+++ b/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
@@ -36,6 +36,22 @@ P.S. In some distros, ``grub-mkrescue`` is called 
``grub2-mkrescue``::
 
   grub-mkrescue -o boot.iso iso
 
+Grub with UEFI
+--------------
+
+This flow is very similar except you need to have the BOOTX64.EFI file.
+You can find this in most Linux distributions::
+
+  iso/
+  └── boot
+      ├── efi
+      │   └── EFI
+      │       └── BOOT
+      │           └── BOOTX64.EFI
+      ├── grub
+      │   └── grub.cfg
+      └── nuttx.elf
+
 QEMU/KVM
 ========
 
@@ -79,6 +95,9 @@ with the pcitest NuttX configuration::
 This will enable the QEMU pci-test and edu PCI test devices which test PIO, 
MMIO, IRQ, and DMA
 functions.  Additionally it will show detailed information about the 
enumeration of the PCI bus.
 
+If you want to boot using UEFI and TianoCore you will need to add a flag like 
this to
+point at OVMF ``--bios /usr/share/edk2/ovmf/OVMF_CODE.fd``
+
 Bochs
 =====
 
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index fac4bb7d61..5e1115ad0e 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -63,10 +63,21 @@ config ARCH_BOARD
 
 endif # ARCH_CHIP_QEMU
 
-config ARCH_EXCLUDE_MULTIBOOT
-       bool "Don't append multiboot2 header"
-       default n
+config ARCH_MULTIBOOT2
+       bool "Append multiboot2 header"
+       default y
        ---help---
-               Some platforms, e.g. jailhouse, do not like to have a multiboot 
header
+               Include a multiboot2 header.  This also provides information to 
the
+               system to enable certain features like the low level 
framebuffer.
+
+if ARCH_MULTIBOOT2
+config MULTBOOT2_FB_TERM
+       bool "Multiboot2 framebuffer terminal"
+       default n
+       depends on NXFONTS
+    ---help---
+       Enable a framebuffer terminal for early debug printing
+
+endif # ARCH_MULTIBOOT2
 
 endif # ARCH_X86_64
diff --git a/arch/x86_64/src/common/x86_64_internal.h 
b/arch/x86_64/src/common/x86_64_internal.h
index da5a5a451e..f98d9605bf 100644
--- a/arch/x86_64/src/common/x86_64_internal.h
+++ b/arch/x86_64/src/common/x86_64_internal.h
@@ -32,6 +32,7 @@
 #  include <nuttx/sched.h>
 #  include <stdint.h>
 #  include <arch/io.h>
+#  include <arch/multiboot2.h>
 #endif
 
 /****************************************************************************
@@ -63,7 +64,7 @@
 #    undef  USE_SERIALDRIVER
 #    undef  USE_EARLYSERIALINIT
 #    undef  CONFIG_DEV_LOWCONSOLE
-#  else
+#  elif defined(CONFIG_16550_UART)
 #    define USE_SERIALDRIVER 1
 #    define USE_EARLYSERIALINIT 1
 #  endif
@@ -195,6 +196,11 @@ void x86_64_checktasks(void);
 
 void x86_64_syscall(uint64_t *regs);
 
+#ifdef CONFIG_ARCH_MULTIBOOT2
+void x86_64_mb2_fbinitialize(struct multiboot_tag_framebuffer *tag);
+void fb_putc(char ch);
+#endif
+
 /* Defined in up_allocateheap.c */
 
 #if CONFIG_MM_REGIONS > 1
diff --git a/arch/x86_64/src/intel64/Make.defs 
b/arch/x86_64/src/intel64/Make.defs
index 010b56acd6..c2d6db49aa 100644
--- a/arch/x86_64/src/intel64/Make.defs
+++ b/arch/x86_64/src/intel64/Make.defs
@@ -38,6 +38,10 @@ CHIP_CSRCS += intel64_serial.c intel64_rng.c 
intel64_check_capability.c
 
 # Configuration-dependent intel64 files
 
+ifeq ($(CONFIG_ARCH_MULTIBOOT2),y)
+CHIP_CSRCS += intel64_mbfb.c
+endif
+
 ifneq ($(CONFIG_SCHED_TICKLESS),y)
 CHIP_CSRCS += intel64_timerisr.c
 endif
diff --git a/arch/x86_64/src/intel64/intel64_head.S 
b/arch/x86_64/src/intel64/intel64_head.S
index 34c7bdf8da..f22b8eb322 100644
--- a/arch/x86_64/src/intel64/intel64_head.S
+++ b/arch/x86_64/src/intel64/intel64_head.S
@@ -65,6 +65,8 @@
     .global     nx_start                        /* nx_start is defined 
elsewhere */
     .global     up_lowsetup                     /* up_lowsetup is defined 
elsewhere */
     .global     g_idle_topstack                 /* The end of the idle stack, 
the start of the heap */
+    .global     mb_info_struct
+    .global     mb_magic
 
     /* These are the page tables */
     .global     pdpt_low
@@ -89,7 +91,7 @@
     .align    8
 
 header_start:
-#ifndef CONFIG_ARCH_EXCLUDE_MULTIBOOT
+#ifdef CONFIG_ARCH_MULTIBOOT2
     .long MULTIBOOT2_HEADER_MAGIC
     .long MULTIBOOT_ARCHITECTURE_I386
     .long HEADER_LENGTH
@@ -97,6 +99,12 @@ header_start:
 
     // multiboot tags go here
 
+    .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
+    .short 0    // flags, none set
+    .long 16     // size, including itself (short + short + long)
+    .long MULTIBOOT_TAG_TYPE_EFI64
+    .long MULTIBOOT_TAG_TYPE_FRAMEBUFFER
+
     .short MULTIBOOT_HEADER_TAG_END
     .short 0    // flags, none set
     .long 8     // size, including itself (short + short + long)
@@ -159,6 +167,10 @@ start32_0:
     .type   __pmode_entry, @function
 __pmode_entry:
 start32:
+#ifdef CONFIG_ARCH_MULTIBOOT2
+    movl %ebx, mb_info_struct
+    movl %eax, mb_magic
+#endif
 
     // initialize rest of the page directory
     lea     pd_low, %edi
diff --git a/arch/x86_64/src/intel64/intel64_lowsetup.c 
b/arch/x86_64/src/intel64/intel64_lowsetup.c
index 51f04e2009..988a9523ff 100644
--- a/arch/x86_64/src/intel64/intel64_lowsetup.c
+++ b/arch/x86_64/src/intel64/intel64_lowsetup.c
@@ -26,6 +26,7 @@
 
 #include <nuttx/arch.h>
 #include <arch/board/board.h>
+#include <arch/multiboot2.h>
 
 #include "x86_64_internal.h"
 
@@ -52,10 +53,48 @@ volatile uint64_t *pt;
 volatile struct ist_s *ist64;
 volatile struct gdt_entry_s *gdt64;
 
+/* This holds information passed by the multiboot2 bootloader */
+
+uint32_t mb_magic __attribute__((section(".loader.bss")));
+uint32_t mb_info_struct __attribute__((section(".loader.bss")));
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
+static void x86_64_mb2_config(void)
+{
+  struct multiboot_tag *tag;
+
+  /* Check that we were actually booted by a mulitboot2 bootloader */
+
+  if (mb_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
+    return;
+
+  for (tag = (struct multiboot_tag *)(uintptr_t)(mb_info_struct + 8);
+    tag->type != MULTIBOOT_TAG_TYPE_END;
+    tag = (struct multiboot_tag *)((uint8_t *)tag + ((tag->size + 7) & ~7)))
+    {
+      switch (tag->type)
+        {
+          case MULTIBOOT_TAG_TYPE_EFI64:
+            {
+              break;
+            }
+
+          case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
+            {
+              x86_64_mb2_fbinitialize(
+                (struct multiboot_tag_framebuffer *)tag);
+              break;
+            }
+
+          default:
+            break;
+        }
+    }
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -94,6 +133,10 @@ void up_lowsetup(void)
 
   x86_64_check_and_enable_capability();
 
+  /* Handle multiboot2 info */
+
+  x86_64_mb2_config();
+
   /* Revoke the lower memory */
 
   __revoke_low_memory();
@@ -102,9 +145,11 @@ void up_lowsetup(void)
 
   x86_64_boardinitialize();
 
+#ifdef USE_EARLYSERIALINIT
   /* Early serial driver initialization */
 
   x86_64_earlyserialinit();
+#endif
 
   x86_64_timer_calibrate_freq();
 
diff --git a/arch/x86_64/src/intel64/intel64_mbfb.c 
b/arch/x86_64/src/intel64/intel64_mbfb.c
new file mode 100644
index 0000000000..f536cffb35
--- /dev/null
+++ b/arch/x86_64/src/intel64/intel64_mbfb.c
@@ -0,0 +1,309 @@
+/****************************************************************************
+ *  arch/x86_64/src/intel64/intel64_lowsetup.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void *baseaddr;
+  uint32_t height;
+  uint32_t width;
+  uint32_t pitch;
+  uint8_t bpp;
+  uint8_t type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t cursor_x;
+  uint32_t cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    return;
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    return;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0
+/****************************************************************************
+ * Function:  fb_test_line
+ *
+ * Description:
+ *   This is a simple test function that can be used to draw a 45deg
+ *   line across the screen.
+ *
+ ****************************************************************************/
+
+static void fb_test_line(void)
+{
+  size_t idx;
+  uint32_t color;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        color = 0xff;
+        break;
+      case 15:
+      case 16:
+        color = 0x7fff;
+        break;
+      case 24:
+        color = 0xffffff;
+        break;
+      case 32:
+        color = 0xffffffff;
+        break;
+      default:
+        return;
+    }
+
+  for (idx = 0; (idx < fb.height) && (idx < fb.width); idx++)
+    {
+      fb_draw_pixel(color, idx, idx);
+    }
+}
+#endif
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+static void fb_scroll(void)
+{
+  void *destp = fb.baseaddr;
+  uint32_t save_rows = ((fb.height / fb_term.font->metrics.mxheight) - 1);
+  size_t row_size = fb.pitch * fb_term.font->metrics.mxheight;
+  uint32_t pxl_row = 0;
+
+  for (; pxl_row < save_rows * fb_term.font->metrics.mxheight; pxl_row++)
+    {
+      memcpy(destp, destp + row_size, fb.pitch);
+      destp += fb.pitch;
+    }
+
+  memset(destp, 0, fb.pitch * (fb.height - pxl_row));
+
+  fb_term.cursor_y -= fb_term.font->metrics.mxheight;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void x86_64_mb2_fbinitialize(struct multiboot_tag_framebuffer *fbt)
+{
+  fb.baseaddr = (void *)(uintptr_t)fbt->common.framebuffer_addr;
+  fb.width = fbt->common.framebuffer_width;
+  fb.height = fbt->common.framebuffer_height;
+  fb.pitch = fbt->common.framebuffer_pitch;
+  fb.bpp = fbt->common.framebuffer_bpp;
+  fb.type = fbt->common.framebuffer_type;
+
+  up_map_region(fb.baseaddr, fb.pitch * fb.height,
+    X86_PAGE_WR | X86_PAGE_PRESENT |
+    X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+
+  fb_clear();
+ 
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+  fb_term_initialize();
+#endif
+
+}
+
+void fb_clear(void)
+{
+  if (fb.baseaddr == NULL)
+    return;
+
+  memset(fb.baseaddr, 0, fb.pitch * fb.height);
+}
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+void fb_term_initialize(void)
+{
+  fb_term.font = nxf_getfonthandle(FONTID_DEFAULT);
+  fb_term.cursor_x = 0;
+  fb_term.cursor_y = 0;
+}
+
+void fb_putc(char ch)
+{
+  uint8_t gly_x;
+  uint8_t gly_y;
+  const struct nx_fontbitmap_s *fbm;
+
+  if (fb.baseaddr == NULL)
+    return;
+
+  if (ch == '\n')
+    {
+      fb_term.cursor_y += fb_term.font->metrics.mxheight;
+      return;
+    }
+
+  if (ch == '\r')
+    {
+      fb_term.cursor_x = 0;
+      return;
+    }
+
+  fbm = nxf_getbitmap((NXHANDLE)fb_term.font, ch);
+  if (fbm == NULL)
+    {
+      fb_putc('.');
+      return;
+    }
+
+  for (gly_y = 0; gly_y < fbm->metric.height; gly_y++)
+    {
+      if (fb_term.cursor_y + gly_y >= fb.height)
+        {
+          fb_scroll();
+          fb_putc(ch);
+          return;
+        }
+
+      for (gly_x = 0; gly_x < fbm->metric.width; gly_x++)
+        {
+          if (fb_term.cursor_x + gly_x >= fb.width)
+            {
+              break;
+            }
+
+          uint8_t stride = (fbm->metric.width + 7) >> 3;
+          uint8_t gly_byte = stride * gly_y + (gly_x >> 3);
+          uint8_t gly_bit = gly_x & 0x7;
+          uint32_t color = 0;  /* Black no matter the color depth */
+          if ((fbm->bitmap[gly_byte] >> (7 - gly_bit)) & 0x01)
+            color = 0xffffffff;  /* Black no matter the color depth */
+
+          fb_draw_pixel(
+            color, fb_term.cursor_x + gly_x, fb_term.cursor_y + gly_y);
+        }
+    }
+
+  fb_term.cursor_x += fbm->metric.width;
+}
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
diff --git a/arch/x86_64/src/intel64/intel64_serial.c 
b/arch/x86_64/src/intel64/intel64_serial.c
index 00896fc1f8..dffd6304c9 100644
--- a/arch/x86_64/src/intel64/intel64_serial.c
+++ b/arch/x86_64/src/intel64/intel64_serial.c
@@ -97,6 +97,10 @@ int up_putc(int ch)
   return ch;
 }
 
+void up_lowputc(char ch)
+{
+  fb_putc(ch);
+}
 #endif /* USE_SERIALDRIVER */
 
 void x86_64_earlyserialinit(void)
diff --git a/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig 
b/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig
new file mode 100644
index 0000000000..3342336c68
--- /dev/null
+++ b/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig
@@ -0,0 +1,72 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_SERIAL is not set
+CONFIG_ARCH="x86_64"
+CONFIG_ARCH_BOARD="qemu-intel64"
+CONFIG_ARCH_BOARD_INTEL64_QEMU=y
+CONFIG_ARCH_CHIP="intel64"
+CONFIG_ARCH_INTEL64_CORE_FREQ_KHZ=2600000
+CONFIG_ARCH_SIZET_LONG=y
+CONFIG_ARCH_X86_64=y
+CONFIG_BOARD_LOOPSPERMSEC=999
+CONFIG_BOOT_RUNFROMEXTSRAM=y
+CONFIG_BUILTIN=y
+CONFIG_CLOCK_MONOTONIC=y
+CONFIG_CONSOLE_SYSLOG=y
+CONFIG_DEBUG_ERROR=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_PCI=y
+CONFIG_DEBUG_PCI_ERROR=y
+CONFIG_DEBUG_PCI_INFO=y
+CONFIG_DEBUG_PCI_WARN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEBUG_WARN=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_HELLO_STACKSIZE=4194304
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=4194304
+CONFIG_LIBM=y
+CONFIG_MAX_TASKS=64
+CONFIG_MULTBOOT2_FB_TERM=y
+CONFIG_NFILE_DESCRIPTORS=32
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFCONFIG=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_READLINE=y
+CONFIG_NXFONTS=y
+CONFIG_NXFONT_MONO5X8=y
+CONFIG_PREALLOC_CHILDSTATUS=16
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_PTHREAD_MUTEX_TYPES=y
+CONFIG_PTHREAD_STACK_DEFAULT=4194304
+CONFIG_PTHREAD_STACK_MIN=4194304
+CONFIG_QEMU_PCI=y
+CONFIG_RAM_SIZE=268435456
+CONFIG_SCHED_CHILD_STATUS=y
+CONFIG_SCHED_HAVE_PARENT=y
+CONFIG_SCHED_IRQMONITOR=y
+CONFIG_SCHED_TICKLESS=y
+CONFIG_SCHED_TICKLESS_ALARM=y
+CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_SIG_DEFAULT=y
+CONFIG_START_DAY=3
+CONFIG_START_MONTH=3
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_CLE=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_TIME64=y
+CONFIG_USEC_PER_TICK=1
+CONFIG_USERMAIN_STACKSIZE=4194304
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_VIRT=y
+CONFIG_VIRT_QEMU_EDU=y
+CONFIG_VIRT_QEMU_PCI_TEST=y

Reply via email to