wok diff linux/stuff/linux-efi.u @ rev 20333

linux: read default cmdline from EFI\BOOT\linux.cmdline
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Jun 02 13:53:27 2018 +0200 (2018-06-02)
parents
children 02ed2446b480
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linux/stuff/linux-efi.u	Sat Jun 02 13:53:27 2018 +0200
     1.3 @@ -0,0 +1,187 @@
     1.4 +--- linux-3.16.53/drivers/firmware/efi/efi-stub-helper.c
     1.5 ++++ linux-3.16.53/drivers/firmware/efi/efi-stub-helper.c
     1.6 +@@ -321,6 +321,77 @@
     1.7 + 
     1.8 + 
     1.9 + /*
    1.10 ++ *
    1.11 ++ */
    1.12 ++static efi_status_t get_file_size(efi_system_table_t *sys_table_arg,
    1.13 ++				  efi_loaded_image_t *image,
    1.14 ++				  efi_char16_t *filename_16,
    1.15 ++				  struct file_info *file)
    1.16 ++{
    1.17 ++	efi_status_t status;
    1.18 ++	efi_file_handle_t *fh = NULL;
    1.19 ++#ifdef CONFIG_X86_64
    1.20 ++	efi_char16_t *p, c;
    1.21 ++#endif
    1.22 ++
    1.23 ++	/* Only open the volume once. */
    1.24 ++	if (!fh) {
    1.25 ++		status = efi_open_volume(sys_table_arg, image,
    1.26 ++					 (void **)&fh);
    1.27 ++		if (status != EFI_SUCCESS)
    1.28 ++			return status;
    1.29 ++	}
    1.30 ++#ifdef CONFIG_X86_64
    1.31 ++	for (p = filename_16; *p != '\0'; p++);
    1.32 ++	c = p[-2];
    1.33 ++	while (1) {
    1.34 ++#endif
    1.35 ++		status = efi_file_size(sys_table_arg, fh, filename_16,
    1.36 ++				       (void **)&file->handle, &file->size);
    1.37 ++#ifdef CONFIG_X86_64
    1.38 ++		if (status != EFI_SUCCESS && p[-2] != '\0') {
    1.39 ++			p[-2] = '\0';
    1.40 ++			continue;
    1.41 ++		}
    1.42 ++		break;
    1.43 ++	}
    1.44 ++	p[-2] = c;
    1.45 ++#endif
    1.46 ++	return status;
    1.47 ++}
    1.48 ++
    1.49 ++/*
    1.50 ++ *
    1.51 ++ */
    1.52 ++static efi_status_t read_efi_file(efi_system_table_t *sys_table_arg,
    1.53 ++			      struct file_info *file,
    1.54 ++			      unsigned long addr,
    1.55 ++			      unsigned long size)
    1.56 ++{
    1.57 ++	efi_status_t status;
    1.58 ++
    1.59 ++	while (size) {
    1.60 ++		unsigned long chunksize;
    1.61 ++		if (size > EFI_READ_CHUNK_SIZE)
    1.62 ++			chunksize = EFI_READ_CHUNK_SIZE;
    1.63 ++		else
    1.64 ++			chunksize = size;
    1.65 ++
    1.66 ++		status = efi_file_read(file->handle,
    1.67 ++				       &chunksize,
    1.68 ++				       (void *)addr);
    1.69 ++		if (status != EFI_SUCCESS) {
    1.70 ++			pr_efi_err(sys_table_arg, "Failed to read file\n");
    1.71 ++			break;
    1.72 ++		}
    1.73 ++		addr += chunksize;
    1.74 ++		size -= chunksize;
    1.75 ++	}
    1.76 ++	efi_file_close(file->handle);
    1.77 ++	return status;
    1.78 ++}
    1.79 ++
    1.80 ++/*
    1.81 +  * Check the cmdline for a LILO-style file= arguments.
    1.82 +  *
    1.83 +  * We only support loading a file from the same filesystem as
    1.84 +@@ -414,18 +485,14 @@
    1.85 + 			}
    1.86 + 		}
    1.87 + 
    1.88 ++#ifdef CONFIG_X86_64
    1.89 ++		*p++ = '6';
    1.90 ++		*p++ = '4';
    1.91 ++#endif
    1.92 + 		*p = '\0';
    1.93 + 
    1.94 +-		/* Only open the volume once. */
    1.95 +-		if (!i) {
    1.96 +-			status = efi_open_volume(sys_table_arg, image,
    1.97 +-						 (void **)&fh);
    1.98 +-			if (status != EFI_SUCCESS)
    1.99 +-				goto free_files;
   1.100 +-		}
   1.101 +-
   1.102 +-		status = efi_file_size(sys_table_arg, fh, filename_16,
   1.103 +-				       (void **)&file->handle, &file->size);
   1.104 ++		status = get_file_size(sys_table_arg,image,filename_16,file);
   1.105 ++	
   1.106 + 		if (status != EFI_SUCCESS)
   1.107 + 			goto close_handles;
   1.108 + 
   1.109 +@@ -433,8 +500,6 @@
   1.110 + 	}
   1.111 + 
   1.112 + 	if (file_size_total) {
   1.113 +-		unsigned long addr;
   1.114 +-
   1.115 + 		/*
   1.116 + 		 * Multiple files need to be at consecutive addresses in memory,
   1.117 + 		 * so allocate enough memory for all the files.  This is used
   1.118 +@@ -454,30 +519,10 @@
   1.119 + 			goto free_file_total;
   1.120 + 		}
   1.121 + 
   1.122 +-		addr = file_addr;
   1.123 + 		for (j = 0; j < nr_files; j++) {
   1.124 +-			unsigned long size;
   1.125 +-
   1.126 +-			size = files[j].size;
   1.127 +-			while (size) {
   1.128 +-				unsigned long chunksize;
   1.129 +-				if (size > EFI_READ_CHUNK_SIZE)
   1.130 +-					chunksize = EFI_READ_CHUNK_SIZE;
   1.131 +-				else
   1.132 +-					chunksize = size;
   1.133 +-
   1.134 +-				status = efi_file_read(files[j].handle,
   1.135 +-						       &chunksize,
   1.136 +-						       (void *)addr);
   1.137 +-				if (status != EFI_SUCCESS) {
   1.138 +-					pr_efi_err(sys_table_arg, "Failed to read file\n");
   1.139 +-					goto free_file_total;
   1.140 +-				}
   1.141 +-				addr += chunksize;
   1.142 +-				size -= chunksize;
   1.143 +-			}
   1.144 +-
   1.145 +-			efi_file_close(files[j].handle);
   1.146 ++			status = read_efi_file(sys_table_arg, &files[j], file_addr, files[j].size);
   1.147 ++			if (status != EFI_SUCCESS)
   1.148 ++				goto free_file_total;
   1.149 + 		}
   1.150 + 
   1.151 + 	}
   1.152 +@@ -649,6 +694,30 @@
   1.153 + 	}
   1.154 + 
   1.155 + 	if (!options_chars) {
   1.156 ++		/* No command line options, look for linux.cmdline */
   1.157 ++#ifdef CONFIG_X86_64
   1.158 ++#define cmdline_name L"EFI\\BOOT\\linux.cmdline64"
   1.159 ++#else
   1.160 ++#define cmdline_name L"EFI\\BOOT\\linux.cmdline"
   1.161 ++#endif
   1.162 ++		struct file_info file;
   1.163 ++		efi_char16_t filename_16[sizeof(cmdline_name)];
   1.164 ++
   1.165 ++		memcpy((void *)filename_16, (void *)cmdline_name, sizeof(cmdline_name));
   1.166 ++		if (get_file_size(sys_table_arg, image, filename_16, &file) != EFI_SUCCESS)
   1.167 ++			goto no_cmdline_file;
   1.168 ++
   1.169 ++		options_bytes = file.size+1;
   1.170 ++		if (efi_low_alloc(sys_table_arg, options_bytes, 0, &cmdline_addr) != EFI_SUCCESS)
   1.171 ++			goto no_cmdline_file;
   1.172 ++
   1.173 ++		*((u8 *)cmdline_addr + file.size) = '\0';
   1.174 ++		if (read_efi_file(sys_table_arg, &file, cmdline_addr, file.size) == EFI_SUCCESS)
   1.175 ++			goto return_cmdline;
   1.176 ++	}
   1.177 ++	no_cmdline_file:
   1.178 ++
   1.179 ++	if (!options_chars) {
   1.180 + 		/* No command line options, so return empty string*/
   1.181 + 		options = &zero;
   1.182 + 	}
   1.183 +@@ -665,6 +734,7 @@
   1.184 + 	s1 = efi_utf16_to_utf8(s1, s2, options_chars);
   1.185 + 	*s1 = '\0';
   1.186 + 
   1.187 ++return_cmdline:
   1.188 + 	*cmd_line_len = options_bytes;
   1.189 + 	return (char *)cmdline_addr;
   1.190 + }