firmware: Add support for loading compressed files
This patch adds the support for loading compressed firmware files. The primary motivation is to reduce the storage size; e.g. currently the files in /lib/firmware on my machine counts up to 419MB, while they can be reduced to 130MB by file compression. The patch introduces a new kconfig option CONFIG_FW_LOADER_COMPRESS. Even with this option set, the firmware loader still tries to load the original firmware file as-is at first, but then falls back to the file with ".xz" extension when it's not found, and the decompressed file content is returned to the caller of request_firmware(). So, no change is needed for the rest. Currently only XZ format is supported. A caveat is that the kernel XZ helper code supports only CRC32 (or none) integrity check type, so you'll have to compress the files via xz -C crc32 option. Since we can't determine the expanded size immediately from an XZ file, the patch re-uses the paged buffer that was used for the user-mode fallback; it puts the decompressed content page, which are vmapped at the end. The paged buffer code is conditionally built with a new Kconfig that is selected automatically. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
5342e7093f
commit
82fd7a8142
@@ -64,12 +64,14 @@ struct fw_priv {
|
||||
void *data;
|
||||
size_t size;
|
||||
size_t allocated_size;
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
||||
bool is_paged_buf;
|
||||
bool need_uevent;
|
||||
struct page **pages;
|
||||
int nr_pages;
|
||||
int page_array_size;
|
||||
#endif
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
bool need_uevent;
|
||||
struct list_head pending_list;
|
||||
#endif
|
||||
const char *fw_name;
|
||||
@@ -133,7 +135,7 @@ static inline void fw_state_done(struct fw_priv *fw_priv)
|
||||
int assign_fw(struct firmware *fw, struct device *device,
|
||||
enum fw_opt opt_flags);
|
||||
|
||||
#ifdef CONFIG_FW_LOADER_USER_HELPER
|
||||
#ifdef CONFIG_FW_LOADER_PAGED_BUF
|
||||
void fw_free_paged_buf(struct fw_priv *fw_priv);
|
||||
int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed);
|
||||
int fw_map_paged_buf(struct fw_priv *fw_priv);
|
||||
|
Reference in New Issue
Block a user