]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1.0.44 release v1.0.44
authorlongpanda <admin@ventoy.net>
Sat, 15 May 2021 11:44:20 +0000 (19:44 +0800)
committerlongpanda <admin@ventoy.net>
Sat, 15 May 2021 11:44:20 +0000 (19:44 +0800)
GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c [new file with mode: 0644]
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
INSTALL/grub/grub.cfg

diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c
new file mode 100644 (file)
index 0000000..92492f9
--- /dev/null
@@ -0,0 +1,316 @@
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/linux.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/term.h>
+
+struct newc_head
+{
+  char magic[6];
+  char ino[8];
+  char mode[8];
+  char uid[8];
+  char gid[8];
+  char nlink[8];
+  char mtime[8];
+  char filesize[8];
+  char devmajor[8];
+  char devminor[8];
+  char rdevmajor[8];
+  char rdevminor[8];
+  char namesize[8];
+  char check[8];
+} GRUB_PACKED;
+
+struct grub_linux_initrd_component
+{
+  grub_file_t file;
+  char *newc_name;
+  grub_off_t size;
+};
+
+struct dir
+{
+  char *name;
+  struct dir *next;
+  struct dir *child;
+};
+
+static char
+hex (grub_uint8_t val)
+{
+  if (val < 10)
+    return '0' + val;
+  return 'a' + val - 10;
+}
+
+static void
+set_field (char *var, grub_uint32_t val)
+{
+  int i;
+  char *ptr = var;
+  for (i = 28; i >= 0; i -= 4)
+    *ptr++ = hex((val >> i) & 0xf);
+}
+
+static grub_uint8_t *
+make_header (grub_uint8_t *ptr,
+            const char *name, grub_size_t len,
+            grub_uint32_t mode,
+            grub_off_t fsize)
+{
+  struct newc_head *head = (struct newc_head *) ptr;
+  grub_uint8_t *optr;
+  grub_size_t oh = 0;
+  grub_memcpy (head->magic, "070701", 6);
+  set_field (head->ino, 0);
+  set_field (head->mode, mode);
+  set_field (head->uid, 0);
+  set_field (head->gid, 0);
+  set_field (head->nlink, 1);
+  set_field (head->mtime, 0);
+  set_field (head->filesize, fsize);
+  set_field (head->devmajor, 0);
+  set_field (head->devminor, 0);
+  set_field (head->rdevmajor, 0);
+  set_field (head->rdevminor, 0);
+  set_field (head->namesize, len);
+  set_field (head->check, 0);
+  optr = ptr;
+  ptr += sizeof (struct newc_head);
+  grub_memcpy (ptr, name, len);
+  ptr += len;
+  oh = ALIGN_UP_OVERHEAD (ptr - optr, 4);
+  grub_memset (ptr, 0, oh);
+  ptr += oh;
+  return ptr;
+}
+
+static void
+free_dir (struct dir *root)
+{
+  if (!root)
+    return;
+  free_dir (root->next);
+  free_dir (root->child);
+  grub_free (root->name);
+  grub_free (root);
+}
+
+static grub_size_t
+insert_dir (const char *name, struct dir **root,
+           grub_uint8_t *ptr)
+{
+  struct dir *cur, **head = root;
+  const char *cb, *ce = name;
+  grub_size_t size = 0;
+  while (1)
+    {
+      for (cb = ce; *cb == '/'; cb++);
+      for (ce = cb; *ce && *ce != '/'; ce++);
+      if (!*ce)
+       break;
+
+      for (cur = *root; cur; cur = cur->next)
+       if (grub_memcmp (cur->name, cb, ce - cb)
+           && cur->name[ce - cb] == 0)
+         break;
+      if (!cur)
+       {
+         struct dir *n;
+         n = grub_zalloc (sizeof (*n));
+         if (!n)
+           return 0;
+         n->next = *head;
+         n->name = grub_strndup (cb, ce - cb);
+         if (ptr)
+           {
+             grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce);
+             ptr = make_header (ptr, name, ce - name,
+                                040777, 0);
+           }
+         size += ALIGN_UP ((ce - (char *) name)
+                           + sizeof (struct newc_head), 4);
+         *head = n;
+         cur = n;
+       }
+      root = &cur->next;
+    }
+  return size;
+}
+
+grub_err_t
+grub_initrd_init (int argc, char *argv[],
+                 struct grub_linux_initrd_context *initrd_ctx)
+{
+  int i;
+  int newc = 0;
+  struct dir *root = 0;
+
+  initrd_ctx->nfiles = 0;
+  initrd_ctx->components = 0;
+
+  initrd_ctx->components = grub_zalloc (argc
+                                       * sizeof (initrd_ctx->components[0]));
+  if (!initrd_ctx->components)
+    return grub_errno;
+
+  initrd_ctx->size = 0;
+
+  for (i = 0; i < argc; i++)
+    {
+      const char *fname = argv[i];
+
+      initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
+
+      if (grub_memcmp (argv[i], "newc:", 5) == 0)
+       {
+         const char *ptr, *eptr;
+         ptr = argv[i] + 5;
+         while (*ptr == '/')
+           ptr++;
+         eptr = grub_strchr (ptr, ':');
+         if (eptr)
+           {
+             initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
+             if (!initrd_ctx->components[i].newc_name)
+               {
+                 grub_initrd_close (initrd_ctx);
+                 return grub_errno;
+               }
+             initrd_ctx->size
+               += ALIGN_UP (sizeof (struct newc_head)
+                           + grub_strlen (initrd_ctx->components[i].newc_name),
+                            4);
+             initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
+                                             &root, 0);
+             newc = 1;
+             fname = eptr + 1;
+           }
+       }
+      else if (newc)
+       {
+         initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
+                                       + sizeof ("TRAILER!!!") - 1, 4);
+         free_dir (root);
+         root = 0;
+         newc = 0;
+       }
+      initrd_ctx->components[i].file = grub_file_open (fname,
+                                                      GRUB_FILE_TYPE_LINUX_INITRD
+                                                      | GRUB_FILE_TYPE_NO_DECOMPRESS);
+      if (!initrd_ctx->components[i].file)
+       {
+         grub_initrd_close (initrd_ctx);
+         return grub_errno;
+       }
+      initrd_ctx->nfiles++;
+      initrd_ctx->components[i].size
+       = grub_file_size (initrd_ctx->components[i].file);
+      initrd_ctx->size += initrd_ctx->components[i].size;
+    }
+
+  if (newc)
+    {
+      initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
+      initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
+                                   + sizeof ("TRAILER!!!") - 1, 4);
+      free_dir (root);
+      root = 0;
+    }
+  
+  return GRUB_ERR_NONE;
+}
+
+grub_size_t
+grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx)
+{
+  return initrd_ctx->size;
+}
+
+void
+grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
+{
+  int i;
+  if (!initrd_ctx->components)
+    return;
+  for (i = 0; i < initrd_ctx->nfiles; i++)
+    {
+      grub_free (initrd_ctx->components[i].newc_name);
+      grub_file_close (initrd_ctx->components[i].file);
+    }
+  grub_free (initrd_ctx->components);
+  initrd_ctx->components = 0;
+}
+
+extern int ventoy_need_prompt_load_file(void);
+extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size);
+grub_err_t
+grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
+                 char *argv[], void *target)
+{
+  grub_uint8_t *ptr = target;
+  int i;
+  int newc = 0;
+  struct dir *root = 0;
+  grub_ssize_t cursize = 0;
+  grub_ssize_t readsize = 0;
+  
+  for (i = 0; i < initrd_ctx->nfiles; i++)
+    {
+      grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
+      ptr += ALIGN_UP_OVERHEAD (cursize, 4);
+
+      if (initrd_ctx->components[i].newc_name)
+       {
+         ptr += insert_dir (initrd_ctx->components[i].newc_name,
+                            &root, ptr);
+         ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
+                            grub_strlen (initrd_ctx->components[i].newc_name),
+                            0100777,
+                            initrd_ctx->components[i].size);
+         newc = 1;
+       }
+      else if (newc)
+       {
+         ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1,
+                            0, 0);
+         free_dir (root);
+         root = 0;
+         newc = 0;
+       }
+
+    cursize = initrd_ctx->components[i].size;
+    if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name && 
+        grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0)
+    {
+        readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize);
+    }
+    else
+    {
+        readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize);
+    }
+
+      if (readsize != cursize)
+       {
+         if (!grub_errno)
+           grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
+                       argv[i]);
+         grub_initrd_close (initrd_ctx);
+         return grub_errno;
+       }
+      ptr += cursize;
+    }
+  if (newc)
+    {
+      grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
+      ptr += ALIGN_UP_OVERHEAD (cursize, 4);
+      ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
+    }
+  free_dir (root);
+  root = 0;
+  return GRUB_ERR_NONE;
+}
index f5256408f2ddbe4f48811e614524241431ab79d0..6383c94497902cf04acda80c7cea8d5c39a9ac3b 100644 (file)
@@ -139,6 +139,9 @@ const char *g_menu_prefix[img_type_max] =
     "iso", "wim", "efi", "img", "vhd", "vtoy"
 };
 
+static int g_vtoy_load_prompt = 0;
+static char g_vtoy_prompt_msg[64];
+
 static int ventoy_get_fs_type(const char *fs)
 {
     if (NULL == fs)
@@ -1043,6 +1046,61 @@ static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc
     return 0;
 }
 
+grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+    (void)ctxt;
+    (void)argc;
+    (void)args;
+
+    g_vtoy_load_prompt = 0;
+    grub_memset(g_vtoy_prompt_msg, 0, sizeof(g_vtoy_prompt_msg));
+    
+    if (argc == 2 && args[0][0] == '1')
+    {
+        g_vtoy_load_prompt = 1;
+        grub_snprintf(g_vtoy_prompt_msg, sizeof(g_vtoy_prompt_msg), "%s", args[1]);
+    }
+
+    VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+int ventoy_need_prompt_load_file(void)
+{
+    return g_vtoy_load_prompt;
+}
+
+grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size)
+{
+    grub_uint64_t ro = 0;
+    grub_uint64_t div = 0;
+    grub_ssize_t left = size;
+    char *cur = (char *)buf;
+
+    grub_printf("\r%s   1%%    ", g_vtoy_prompt_msg); 
+    grub_refresh();
+
+    while (left >= VTOY_SIZE_2MB)
+    {
+        grub_file_read(file, cur, VTOY_SIZE_2MB);
+        cur += VTOY_SIZE_2MB;
+        left -= VTOY_SIZE_2MB;
+
+        div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro);
+        grub_printf("\r%s   %d%%    ", g_vtoy_prompt_msg, (int)div);
+        grub_refresh();  
+    }
+
+    if (left > 0)
+    {
+        grub_file_read(file, cur, left);
+    }
+
+    grub_printf("\r%s   100%%     \n", g_vtoy_prompt_msg);
+    grub_refresh(); 
+
+    return size;
+}
+
 static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args)
 {
     int rc = 1;
@@ -1089,7 +1147,14 @@ static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int ar
         return 1;
     }
 
-    grub_file_read(file, buf, file->size);
+    if (g_vtoy_load_prompt)
+    {
+         ventoy_load_file_with_prompt(file, buf, file->size);
+    }
+    else
+    {
+        grub_file_read(file, buf, file->size);
+    }
 
     grub_snprintf(name, sizeof(name), "%s_addr", args[2]);
     grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
@@ -4507,6 +4572,7 @@ static cmd_para ventoy_cmds[] =
     { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL },
     { "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL },
     { "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL },
+    { "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL },
 
 };
 
index 8e2527bf0af602096c9edde78f6b380f429b8648..37e46c19bd15731cd5bef1c74a0e9bc329b368db 100644 (file)
@@ -29,6 +29,8 @@
 
 #define VTOY_SIZE_1GB     1073741824
 #define VTOY_SIZE_1MB     (1024 * 1024)
+#define VTOY_SIZE_2MB     (2 * 1024 * 1024)
+#define VTOY_SIZE_4MB     (4 * 1024 * 1024)
 #define VTOY_SIZE_512KB   (512 * 1024)
 #define VTOY_SIZE_1KB     1024
 
@@ -564,6 +566,9 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
 grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
 grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args);
+grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args);
+grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size);
+int ventoy_need_prompt_load_file(void);
 
 VTOY_JSON *vtoy_json_find_item
 (
index d62b71df239da21fd320518bbd90fa9009243fbe..21b7116fdaf606e84bddff50feaa8fcc95febd4f 100644 (file)
@@ -848,13 +848,14 @@ function vtoy_windows_wimboot_func {
         linux16  "$vtoy_path/$vt_wimkernel"  quiet
         ventoy_debug_pause
 
-        echo Loading files...... (This may take a few minutes, please wait)
+        vt_set_wim_load_prompt 1 "Loading files......"
         initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \
              newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
              newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \
              newc:bcd:$vtoy_wimboot_prefix/boot/bcd \
              newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \
              newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim
+        vt_set_wim_load_prompt 0
         boot
     else
         if [ "$grub_cpu" = "i386" ]; then
@@ -863,8 +864,10 @@ function vtoy_windows_wimboot_func {
             set vt_wimkernel=wimboot.x86_64.xz
         fi
 
-        echo Loading files...... (This may take a few minutes, please wait)
+        vt_set_wim_load_prompt 1 "Loading files......"
         vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem
+        vt_set_wim_load_prompt 0
+
         if [ $? -eq 0 ]; then
             set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size}
         else
@@ -1793,7 +1796,7 @@ function img_unsupport_menuentry {
 #############################################################
 #############################################################
 
-set VENTOY_VERSION="1.0.43"
+set VENTOY_VERSION="1.0.44"
 
 #ACPI not compatible with Window7/8, so disable by default
 set VTOY_PARAM_NO_ACPI=1