jailhouseのmain.cを見ていてファームウェアの読み込みrequest_firmware()のところでこれってどうやってんだろ?と思ったので調べてみるなど。見たカーネルのバージョンは3.12です。
この関数がどんなことをしているのかというのはLinux Kernel Watchにありました。こちらによるとrequest_firmware()自体がファームウェアを読み込むのではなく、ユーザー空間側のプログラムと連動してファームウェアの読み込みが行われるのですね。
では実際に見ていくと。。。
jailhouse側はこのような呼び出し。
const struct firmware *hypervisor; ~ 中略 ~ err = request_firmware(&hypervisor, JAILHOUSE_FW_NAME, jailhouse_dev);
JAILHOUSE_FW_NAMEはjailhouse.bin、jailhouse_devはmodule_initの関数で設定したデバイス。
request_firmware()はこうなってます。。
1129 int 1130 request_firmware(const struct firmware **firmware_p, const char *name, 1131 struct device *device) 1132 { 1133 int ret; 1134 1135 /* Need to pin this module until return */ 1136 __module_get(THIS_MODULE); 1137 ret = _request_firmware(firmware_p, name, device, true, false); 1138 module_put(THIS_MODULE); 1139 return ret; 1140 }
関数の実質的な内容は_request_firmware()ですね。
request_firmware()に渡す引数についてはコメントに内容が書かれています。
1111 * @firmware_p: pointer to firmware image 1112 * @name: name of firmware file 1113 * @device: device for which firmware is being loaded
firmware_pには変数hypervisorのポインタのポインタを渡しているのでイメージがここに入るはず。nameはjailhouse.bin、デバイスはjailhouseが使うstruct device。
_request_firmware()はこちら。
1056 _request_firmware(const struct firmware **firmware_p, const char *name, 1057 struct device *device, bool uevent, bool nowait) 1058 { 1059 struct firmware *fw; 1060 long timeout; 1061 int ret; 1062 1063 if (!firmware_p) 1064 return -EINVAL; 1065 1066 ret = _request_firmware_prepare(&fw, name, device); 1067 if (ret <= 0) /* error or already assigned */ 1068 goto out; 1069 1070 ret = 0; 1071 timeout = firmware_loading_timeout(); 1072 if (nowait) { 1073 timeout = usermodehelper_read_lock_wait(timeout); 1074 if (!timeout) { 1075 dev_dbg(device, "firmware: %s loading timed out\n", 1076 name); 1077 ret = -EBUSY; 1078 goto out; 1079 } 1080 } else { 1081 ret = usermodehelper_read_trylock(); 1082 if (WARN_ON(ret)) { 1083 dev_err(device, "firmware: %s will not be loaded\n", 1084 name); 1085 goto out; 1086 } 1087 } 1088 1089 if (!fw_get_filesystem_firmware(device, fw->priv)) 1090 ret = fw_load_from_user_helper(fw, name, device, 1091 uevent, nowait, timeout); 1092 1093 /* don't cache firmware handled without uevent */ 1094 if (!ret) 1095 ret = assign_firmware_buf(fw, device, !uevent); 1096 1097 usermodehelper_read_unlock(); 1098 1099 out: 1100 if (ret < 0) { 1101 release_firmware(fw); 1102 fw = NULL; 1103 } 1104 1105 *firmware_p = fw; 1106 return ret; 1107 }
この間数の内容を大雑把にまとめるとこのような形。
- _request_firmware_prepare()で読み込み準備
- 1071~1088行目でユーザー空間側のプログラムがファームウェアを読み込むのを待つ
- fw_get_filesystem_firmware()でファームウェアを読み込んでfw->privに保存
では、_request_firmware_prepare()を見てみます。
977 static int 978 _request_firmware_prepare(struct firmware **firmware_p, const char *name, 979 struct device *device) 980 { 981 struct firmware *firmware; 982 struct firmware_buf *buf; 983 int ret; 984 985 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); 986 if (!firmware) { 987 dev_err(device, "%s: kmalloc(struct firmware) failed\n", 988 __func__); 989 return -ENOMEM; 990 } 991 992 if (fw_get_builtin_firmware(firmware, name)) { 993 dev_dbg(device, "firmware: using built-in firmware %s\n", name); 994 return 0; /* assigned */ 995 } 996 997 ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); 998 999 /* 1000 * bind with 'buf' now to avoid warning in failure path 1001 * of requesting firmware. 1002 */ 1003 firmware->priv = buf; 1004 1005 if (ret > 0) { 1006 ret = sync_cached_firmware_buf(buf); 1007 if (!ret) { 1008 fw_set_page_data(buf, firmware); 1009 return 0; /* assigned */ 1010 } 1011 } 1012 1013 if (ret < 0) 1014 return ret; 1015 return 1; /* need to load */ 1016 }
この関数はロードしようしているファームウェアがカーネルビルトインのものかチェック(fw_get_builtin_firmware())してビルトインファームウェアの場合は0、違う場合は1を返す。
ビルトインファームウェアだった場合は_request_firmware()に戻ってそのまま終了。
対象のファームウェアがビルトインかどうかはfw_get_builtin_firmware()でチェック。調べ方は__start_builtin_fw~__end_builtin_fwの範囲でnameが有るか調べて有ったらtrueをかえすというもの。
44 extern struct builtin_fw __start_builtin_fw[]; 45 extern struct builtin_fw __end_builtin_fw[]; 46 47 static bool fw_get_builtin_firmware(struct firmware *fw, const char *name) 48 { 49 struct builtin_fw *b_fw; 50 51 for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { 52 if (strcmp(name, b_fw->name) == 0) { 53 fw->size = b_fw->size; 54 fw->data = b_fw->data; 55 return true; 56 } 57 } 58 59 return false; 60 }
もしここからファームウェアが見つからなければfw_lookup_and_allocate_buf()を使う。
197 static int fw_lookup_and_allocate_buf(const char *fw_name, 198 struct firmware_cache *fwc, 199 struct firmware_buf **buf) 200 { 201 struct firmware_buf *tmp; 202 203 spin_lock(&fwc->lock); 204 tmp = __fw_lookup_buf(fw_name); 205 if (tmp) { 206 kref_get(&tmp->ref); 207 spin_unlock(&fwc->lock); 208 *buf = tmp; 209 return 1; 210 } 211 tmp = __allocate_fw_buf(fw_name, fwc); 212 if (tmp) 213 list_add(&tmp->list, &fwc->head); 214 spin_unlock(&fwc->lock); 215 216 *buf = tmp; 217 218 return tmp ? 0 : -ENOMEM; 219 }
この関数はファームウェアバッファのキャッシュを検索してファームウェアが読み込まれている場合はそのバッファを返す。
キャッシュから検索しているのは__fw_lookup_buf()で以下のような内容。
186 static struct firmware_buf *__fw_lookup_buf(const char *fw_name) 187 { 188 struct firmware_buf *tmp; 189 struct firmware_cache *fwc = &fw_cache; 190 191 list_for_each_entry(tmp, &fwc->head, list) 192 if (!strcmp(tmp->fw_id, fw_name)) 193 return tmp; 194 return NULL; 195 }
キャッシュから見つからなかった場合は__allocate_fw_buf()でバッファを確保する。
163 static struct firmware_buf *__allocate_fw_buf(const char *fw_name, 164 struct firmware_cache *fwc) 165 { 166 struct firmware_buf *buf; 167 168 buf = kzalloc(sizeof(*buf) + strlen(fw_name) + 1 , GFP_ATOMIC); 169 170 if (!buf) 171 return buf; 172 173 kref_init(&buf->ref); 174 strcpy(buf->fw_id, fw_name); 175 buf->fwc = fwc; 176 init_completion(&buf->completion); 177 #ifdef CONFIG_FW_LOADER_USER_HELPER 178 INIT_LIST_HEAD(&buf->pending_list); 179 #endif 180 181 pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); 182 183 return buf; 184 }
kzalloc()で構造体サイズの他にファームウェア名を付けているのはfirmware_buf構造体の最後のメンバ(fw_id)がchar[]で可変長になっているため。
121 struct firmware_buf { 122 struct kref ref; 123 struct list_head list; 124 struct completion completion; ~中略~ 137 char fw_id[]; 138 };
ここまででキャッシュからファームウェアのバッファが見つかった、もしくはアローケート完了です。そして_request_firmware()に戻ってファームウェアの読み込み部分で、読み込みを行うのはfw_get_filesystem_firmware()。
305 static bool fw_get_filesystem_firmware(struct device *device, 306 struct firmware_buf *buf) 307 { 308 int i; 309 bool success = false; 310 char *path = __getname(); 311 312 for (i = 0; i < ARRAY_SIZE(fw_path); i++) { 313 struct file *file; 314 315 /* skip the unset customized path */ 316 if (!fw_path[i][0]) 317 continue; 318 319 snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); 320 321 file = filp_open(path, O_RDONLY, 0); 322 if (IS_ERR(file)) 323 continue; 324 success = fw_read_file_contents(file, buf); 325 fput(file); 326 if (success) 327 break; 328 } 329 __putname(path); 330 331 if (success) { 332 dev_dbg(device, "firmware: direct-loading firmware %s\n", 333 buf->fw_id); 334 mutex_lock(&fw_lock); 335 set_bit(FW_STATUS_DONE, &buf->status); 336 complete_all(&buf->completion); 337 mutex_unlock(&fw_lock); 338 } 339 340 return success; 341 }
最初の__getname()は何だ?と思ったらスラブキャッシュからメモリを取得するためのマクロでした。
2048 #define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) 2049 #define __putname(name) kmem_cache_free(names_cachep, (void *)(name))
そして、ファイルの読み込みですがファイル名は分かっているけどパスが分からないのでそのためのループですね。
パスの配列分ループしていますがこの配列はfirmware_class.cに定義されています。
254 /* direct firmware loading support */ 255 static char fw_path_para[256]; 256 static const char * const fw_path[] = { 257 fw_path_para, 258 "/lib/firmware/updates/" UTS_RELEASE, 259 "/lib/firmware/updates", 260 "/lib/firmware/" UTS_RELEASE, 261 "/lib/firmware" 262 };
あとはファイルを開いてみてオープンに成功すればfw_read_file_contents()で読み込むという流れですね。
一応、fw_read_file_contents()がどんなことをしているか見てます。
285 static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) 286 { 287 long size; 288 char *buf; 289 290 size = fw_file_size(file); 291 if (size <= 0) 292 return false; 293 buf = vmalloc(size); 294 if (!buf) 295 return false; 296 if (kernel_read(file, 0, buf, size) != size) { 297 vfree(buf); 298 return false; 299 } 300 fw_buf->data = buf; 301 fw_buf->size = size; 302 return true; 303 }
ファイルの読み込みを行っているのはkernel_read()で関数のプロトタイプは以下の通り。
792 int kernel_read(struct file *file, loff_t offset, 793 char *addr, unsigned long count)
ファイルオフセット0からsize分読み出しているだけですね。
もしfw_get_filesystem_firmware()でファームウェアの読み込みに失敗した場合はfw_load_from_user_helper()が呼ばれる。
1089 if (!fw_get_filesystem_firmware(device, fw->priv)) 1090 ret = fw_load_from_user_helper(fw, name, device, 1091 uevent, nowait, timeout);
fw_load_from_user_helper()はこのような関数。
905 static int fw_load_from_user_helper(struct firmware *firmware, 906 const char *name, struct device *device, 907 bool uevent, bool nowait, long timeout) 908 { 909 struct firmware_priv *fw_priv; 910 911 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); 912 if (IS_ERR(fw_priv)) 913 return PTR_ERR(fw_priv); 914 915 fw_priv->buf = firmware->priv; 916 return _request_firmware_load(fw_priv, uevent, timeout); 917 } 918
fw_create_instance()と_request_firmware_load()の呼び出しが主な処理。
fw_create_instance()の処理としてはfirmware_priv構造体の設定とファームウェア名のデバイスファイルの作成ってところですかね。
814 static struct firmware_priv * 815 fw_create_instance(struct firmware *firmware, const char *fw_name, 816 struct device *device, bool uevent, bool nowait) 817 { 818 struct firmware_priv *fw_priv; 819 struct device *f_dev; 820 821 fw_priv = kzalloc(sizeof(*fw_priv), GFP_KERNEL); 822 if (!fw_priv) { 823 dev_err(device, "%s: kmalloc failed\n", __func__); 824 fw_priv = ERR_PTR(-ENOMEM); 825 goto exit; 826 } 827 828 fw_priv->nowait = nowait; 829 fw_priv->fw = firmware; 830 INIT_DELAYED_WORK(&fw_priv->timeout_work, 831 firmware_class_timeout_work); 832 833 f_dev = &fw_priv->dev; 834 835 device_initialize(f_dev); 836 dev_set_name(f_dev, "%s", fw_name); 837 f_dev->parent = device; 838 f_dev->class = &firmware_class; 839 exit: 840 return fw_priv; 841 }
firmware_priv構造体はこのように定義されています。CONFIG_FW_LOADER_USER_HELPERがyじゃないとダメですね。
426 /* 427 * user-mode helper code 428 */ 429 #ifdef CONFIG_FW_LOADER_USER_HELPER 430 struct firmware_priv { 431 struct delayed_work timeout_work; 432 bool nowait; 433 struct device dev; 434 struct firmware_buf *buf; 435 struct firmware *fw; 436 }; 437
_request_firmware_load()がユーザーモードと連動してファームウェアを読み込むメインの処理っぽいですね。
842 843 /* load a firmware via user helper */ 844 static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, 845 long timeout) 846 { 847 int retval = 0; 848 struct device *f_dev = &fw_priv->dev; 849 struct firmware_buf *buf = fw_priv->buf; 850 851 /* fall back on userspace loading */ 852 buf->is_paged_buf = true; 853 854 dev_set_uevent_suppress(f_dev, true); 855 856 retval = device_add(f_dev); 857 if (retval) { 858 dev_err(f_dev, "%s: device_register failed\n", __func__); 859 goto err_put_dev; 860 } 861 862 retval = device_create_bin_file(f_dev, &firmware_attr_data); 863 if (retval) { 864 dev_err(f_dev, "%s: sysfs_create_bin_file failed\n", __func__); 865 goto err_del_dev; 866 } 867 868 mutex_lock(&fw_lock); 869 list_add(&buf->pending_list, &pending_fw_head); 870 mutex_unlock(&fw_lock); 871 872 retval = device_create_file(f_dev, &dev_attr_loading); 873 if (retval) { 874 mutex_lock(&fw_lock); 875 list_del_init(&buf->pending_list); 876 mutex_unlock(&fw_lock); 877 dev_err(f_dev, "%s: device_create_file failed\n", __func__); 878 goto err_del_bin_attr; 879 } 880 881 if (uevent) { 882 buf->need_uevent = true; 883 dev_set_uevent_suppress(f_dev, false); 884 dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); 885 if (timeout != MAX_SCHEDULE_TIMEOUT) 886 schedule_delayed_work(&fw_priv->timeout_work, timeout); 887 888 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); 889 } 890 891 wait_for_completion(&buf->completion); 892 893 cancel_delayed_work_sync(&fw_priv->timeout_work); 894 895 device_remove_file(f_dev, &dev_attr_loading); 896 err_del_bin_attr: 897 device_remove_bin_file(f_dev, &firmware_attr_data); 898 err_del_dev: 899 device_del(f_dev); 900 err_put_dev: 901 put_device(f_dev); 902 return retval; 903 }
読み込んだデータの保存先になるファイルを作り、読み込みが終わるのを待つ。そして最後に作ったファイルを削除して終了。
そしてまた_request_firmware()に戻ってきて、retが0だった場合のみassign_firmware_buf()が呼ばれる。retが0とは例えば、 fw_load_from_user_helper()が成功したときとか。
1093 /* don't cache firmware handled without uevent */ 1094 if (!ret) 1095 ret = assign_firmware_buf(fw, device, !uevent); 1096
assign_firmware_buf()はコメントが書かれていて良いですね( ´∀`)bグッ!
1018 static int assign_firmware_buf(struct firmware *fw, struct device *device, 1019 bool skip_cache) 1020 { 1021 struct firmware_buf *buf = fw->priv; 1022 1023 mutex_lock(&fw_lock); 1024 if (!buf->size || is_fw_load_aborted(buf)) { 1025 mutex_unlock(&fw_lock); 1026 return -ENOENT; 1027 } 1028 1029 /* 1030 * add firmware name into devres list so that we can auto cache 1031 * and uncache firmware for device. 1032 * 1033 * device may has been deleted already, but the problem 1034 * should be fixed in devres or driver core. 1035 */ 1036 if (device && !skip_cache) 1037 fw_add_devm_name(device, buf->fw_id); 1038 1039 /* 1040 * After caching firmware image is started, let it piggyback 1041 * on request firmware. 1042 */ 1043 if (buf->fwc->state == FW_LOADER_START_CACHE) { 1044 if (fw_cache_piggyback_on_request(buf->fw_id)) 1045 kref_get(&buf->ref); 1046 } 1047 1048 /* pass the pages buffer to driver at the last minute */ 1049 fw_set_page_data(buf, fw); 1050 mutex_unlock(&fw_lock); 1051 return 0; 1052 }
( ´ー`)フゥー...
適当にまとめると
- request_firmware()はファームウェア名を受け取ってそのファイルを読み込む
- ファームウェアはカーネルビルトインのものとそれ以外の2種類
- ファームウェアの読み込みはカーネル内部で行える場合と、ユーザー空間のプログラムに読んでもらう場合の2通りある
- 読み込んだファームウェアのデータはキャッシュされる