grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 6/7] add ARM Linux loader


From: Leif Lindholm
Subject: Re: [PATCH 6/7] add ARM Linux loader
Date: Wed, 3 Apr 2013 17:30:05 +0000
User-agent: Mutt/1.5.20 (2009-06-14)

On Mon, Apr 01, 2013 at 06:18:17PM +0200, Francesco Lavra wrote:
> On 03/24/2013 06:01 PM, Leif Lindholm wrote:
> > === added directory 'grub-core/loader/arm'
> > === added file 'grub-core/loader/arm/linux.c'
> > --- grub-core/loader/arm/linux.c    1970-01-01 00:00:00 +0000
> > +++ grub-core/loader/arm/linux.c    2013-03-24 13:49:04 +0000
[...]
> > +static grub_addr_t initrd_start;
> > +static grub_size_t initrd_end;
> 
> initrd_end should be the same type as initrd_start.
 
Clearly.

[...]
> > +static grub_err_t
> > +linux_prepare_fdt (void)
> > +{
> > +  int node;
> > +  int retval;
> > +  int tmp_size;
> > +  void *tmp_fdt;
> > +
> > +  tmp_size = fdt_totalsize ((void *) boot_data) + 
> > FDT_ADDITIONAL_ENTRIES_SIZE;
> 
> Having a fixed size limit (FDT_ADDITIONAL_ENTRIES_SIZE) to insert
> variable-sized data (such as the linux command line) seems suboptimal,
> as this may fail when a very long command line is passed. How about
> removing the FDT_ADDITIONAL_ENTRIES_SIZE define from the header file
> include/grub/arm/linux.h (after all, this is an implementation detail
> and IMHO shouldn't go in a public header file) and defining it in this
> function, say:
> 
> #define FDT_ADDITIONAL_ENTRIES_SIZE   (0x100 +        \
>       grub_strlen (linux_args))
 
Mmm. It was only used in one location though, so I'll use your suggestion,
but just inline it.

> [...]
> > +#ifdef GRUB_MACHINE_EFI
> > +  linux_addr = (grub_addr_t) grub_efi_allocate_loader_memory 
> > (LINUX_PHYS_OFFSET, size);
> 
> There should be a check against allocation failure.
 
Yes, this is a global issue with this loader under EFI - dealing with memory
allocation/deallocation. Will be resolved in next version.

> > +static grub_err_t
> > +linux_unload (void)
> > +{
> > +  grub_dl_unref (my_mod);
> > +
> > +  grub_free (linux_args);
> > +  linux_args = NULL;
> 
> linux_args might already be NULL, if memory allocation for it failed in
> grub_cmd_linux().

Yes, but on the other hand grub_free (like libc free) checks for NULL.

> In the EFI case, the memory allocated for the kernel image should be
> freed as well.
 
Yes.

> > +
> > +  initrd_start = initrd_end = 0;
> 
> Why should the initrd data be discarded here?
 
It probably shouldn't.

> > +
> > +  return GRUB_ERR_NONE;
> > +}
> > +static grub_err_t
> > +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
> > +           int argc, char *argv[])
> > +{
> > +  int size, retval;
> 
> The return type of linux_load() is grub_err_t, so retval should be the
> same type.
> 
> > +  grub_file_t file;
> > +  grub_dl_ref (my_mod);
> > +
> > +  if (argc == 0)
> > +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> > +
> > +  file = grub_file_open (argv[0]);
> > +  if (!file)
> > +    goto fail;
> > +
> > +  retval = linux_load (argv[0]);
> 
> Here the file is already open: why not just pass the file handle to
> linux_load()?
 
Unfortunate leftover from earlier version, thanks.

> > +  grub_file_close (file);
> > +  if (retval != GRUB_ERR_NONE)
> > +    goto fail;
> 
> In order to correctly report all error types, grub_errno should be set
> to retval before entering the error path.
 
OK, adding grub_error() to all failure paths in linux_load.

> > +
> > +  grub_loader_set (linux_boot, linux_unload, 1);
> 
> Since linux_boot() may return control to its caller, the third argument
> of grub_loader_set() should be 0, otherwise linux_boot() returning
> control to its caller results in a dysfunctional state.
 
OK.

> > +
> > +  size = grub_loader_cmdline_size (argc, argv);
> > +  linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
> > +  if (!linux_args)
> > +    goto fail;
> 
> grub_loader_unset() should be called in this error path, otherwise if
> one tries to boot in this state, linux_prepare_fdt() will access a NULL
> pointer.
 
Yes.

> > +  if (grub_file_read (file, (void *) initrd_start, size) != size)
> > +    goto fail;
> 
> In the EFI case, the memory allocated for the initrd should be freed
> here. And in both EFI and U-Boot cases, initrd_start should be zeroed.
 
Yes.

> > +#else
> > +  boot_data = LINUX_FDT_ADDRESS;
> > +#endif
> > +  grub_dprintf ("loader", "Loading device tree to 0x%08x\n",
> > +           (grub_addr_t) boot_data);
> > +  fdt_move (blob, (void *) boot_data, fdt_totalsize (blob));
> > +  grub_free (blob);
> 
> I don't get the point of allocating memory for the FDT in load_dtb()
> just to move the FDT data to boot_data and then freeing the temporary
> memory. Isn't it easier if load_dtb() operates directly on boot_data?
 
Maybe not the sanest of reasons, but the U-Boot port permits passing
through ATAGs if no FDT is available, so I prefer not corrupting
boot_data until a successful load has occurred.

> > +
> > +  /* 
> > +   * We've successfully loaded an FDT, so any machine type passed
> > +   * from firmware is now obsolete.
> > +   */
> > +  machine_type = ARM_FDT_MACHINE_TYPE;
> > +
> > +  return GRUB_ERR_NONE;
> 
> The file should be closed before returning.

Yes.

/
    Leif



reply via email to

[Prev in Thread] Current Thread [Next in Thread]