This source file includes following definitions.
- hash_module_name
- get_module_path
- get_buffer
- b_open
- b_read
- b_close
- namecmp
- module_find
- moduleload_error
- module_do_relocations
- module_find_symbol_address
- module_do_imports
- module_do_action
- module_writeline
- module_log_hdr
- module_log_clear
- module_log_load
- module_log_unload
- bind_module
- module_unload_idx
- module_unload
- validate
- load_module_file
- link_module
- module_preload
- _module_load
- module_load
- module_run_error
- default_run
- default_run0
- default_run1
- default_run2
- default_run3
- module_run
- module_exit_alt
- module_tick_unloader
- module_get_adr
- get_module_info
1
2
3
4
5
6
7
8
9 #include "camera_info.h"
10 #include "conf.h"
11 #include "console.h"
12 #include "clock.h"
13 #include "cache.h"
14 #include "lang.h"
15 #include "gui_mbox.h"
16 #include "gui_lang.h"
17 #include "time.h"
18 #include "ctype.h"
19
20 #include "simple_module.h"
21 #include "module_load.h"
22 #include "module_exportlist.h"
23 #include "module_hash.h"
24
25
26
27
28
29 extern sym_hash symbol_hash_table[];
30
31
32
33
34 static module_entry modules[MAX_NUM_LOADED_MODULES];
35
36
37
38 #define BUFFER_FOR_READ_SIZE 4096
39 #define MODULES_PATH "A/CHDK/MODULES/"
40
41
42
43
44 static unsigned int hash_module_name(char *str)
45 {
46 unsigned int hash = 5381;
47 int c;
48
49
50 while ((c = *str++) != 0)
51 hash = ((hash << 5) + hash) ^ toupper(c);
52
53 return hash;
54 }
55
56
57
58
59
60 static unsigned int get_module_path(char *path, const char *name)
61 {
62
63 if ((tolower(name[0]) != 'a') || (name[1] != '/'))
64 strcpy(path, MODULES_PATH);
65 else
66 path[0] = 0;
67
68 strcat(path, name);
69
70 return hash_module_name(path);
71 }
72
73
74
75
76
77
78
79 static char* buf_load = 0;
80 static int buf_size = 0;
81
82
83
84
85 static int get_buffer(int size)
86 {
87 size = (size + 3) & 0xFFFFFFFC;
88 if (size > buf_size)
89 {
90 if (buf_load)
91 {
92 ufree(buf_load);
93 buf_load = 0;
94 buf_size = 0;
95 }
96 buf_load = umalloc(size);
97 if (buf_load)
98 buf_size = size;
99 }
100
101 return buf_size;
102 }
103
104
105
106 static int b_open(const char* name)
107 {
108 if (!get_buffer(BUFFER_FOR_READ_SIZE))
109 {
110 return -1;
111 }
112
113 return open(name, O_RDONLY, 0777);
114 }
115
116
117
118
119 int b_read(int fd, char* buf, int len)
120 {
121 int loaded = 0, now = 1;
122
123 while (now && loaded<len)
124 {
125 now = len - loaded;
126 if (now > buf_size)
127 now = buf_size;
128
129 now = read(fd, buf_load, now);
130 memcpy(buf+loaded, buf_load, now);
131 loaded += now;
132 }
133
134 return loaded;
135 }
136
137
138 void b_close(int fd)
139 {
140 if (fd >= 0)
141 close(fd);
142 }
143
144
145
146
147
148
149
150 static int namecmp(const char* s1, const char* s2)
151 {
152 if ((s1 == 0) && (s2 == 0)) return 1;
153 if ((s1 == 0) || (s2 == 0)) return 0;
154 while (*s1 && *s2)
155 {
156 if (tolower(*s1) != tolower(*s2)) return 0;
157 s1++;
158 s2++;
159 }
160 return ((*s1 == 0) && (*s2 == 0));
161 }
162
163
164
165
166
167 static int module_find(unsigned int hash)
168 {
169 int i;
170
171 for (i=0; i<MAX_NUM_LOADED_MODULES; i++)
172 {
173 if (modules[i].hdr && (modules[i].hName == hash))
174 {
175 return i;
176 }
177 }
178 return -1;
179 }
180
181
182
183 static void moduleload_error(const char* name, const char* text)
184 {
185 extern volatile int chdk_started_flag;
186 if (chdk_started_flag)
187 {
188 char buf[100];
189 sprintf(buf, "Fail to load %s: %s", name, text);
190
191 console_clear();
192 console_add_line(buf);
193 msleep(1000);
194 }
195 }
196
197
198
199
200
201
202
203
204
205 static int module_do_relocations(flat_hdr* flat, void* relocbuf, uint32_t reloc_count)
206 {
207 uint32_t i;
208 unsigned char* buf = (unsigned char*)flat;
209 uint32_t* rbuf = (uint32_t*)relocbuf;
210
211 for (i=0; i < reloc_count; i++)
212 {
213
214 *(uint32_t*)(buf+rbuf[i]) += (uint32_t)buf;
215 }
216
217 return 1;
218 }
219
220
221
222
223 static const void* module_find_symbol_address(uint32_t importid)
224 {
225 int min = 0, max = EXPORTLIST_COUNT-1;
226 do
227 {
228 int mid = (min + max) >> 1;
229 if (importid == symbol_hash_table[mid].hash)
230 return symbol_hash_table[mid].address;
231 else if (importid > symbol_hash_table[mid].hash)
232 min = mid + 1;
233 else
234 max = mid - 1;
235 } while (min <= max);
236 return 0;
237 }
238
239
240
241
242
243
244
245
246
247
248 static int module_do_imports(flat_hdr* flat, void* relocbuf, uint32_t import_count)
249 {
250 uint32_t i;
251 unsigned char* buf = (unsigned char*)flat;
252 uint32_t* rbuf = (uint32_t*)relocbuf;
253
254 for (i=0; i < import_count;)
255 {
256
257 int importaddress = (int)module_find_symbol_address(rbuf[i++]);
258 if (importaddress == 0) return 0;
259
260
261 int cnt = rbuf[i] >> 24;
262
263 for (; cnt>0; cnt--)
264 {
265
266 uint32_t offs = rbuf[i++] & 0x00FFFFFF;
267
268 *(uint32_t*)(buf+offs) += importaddress;
269 }
270 }
271 return 1;
272 }
273
274
275
276
277 static int module_do_action(int fd, flat_hdr* mod, uint32_t offset, uint32_t segment_size, int (*func)(flat_hdr*, void*, uint32_t))
278 {
279 if (segment_size > 0)
280 {
281 if (lseek(fd, offset, SEEK_SET) == (int)offset)
282 {
283 if (read(fd, buf_load, segment_size) == (int)segment_size)
284 {
285
286 return func(mod, (uint32_t*)buf_load, segment_size >> 2);
287 }
288 }
289 return 0;
290 }
291 return 1;
292 }
293
294
295
296
297
298
299
300
301
302 static void module_writeline(char *buf)
303 {
304 if (conf.module_logging)
305 {
306 int fd = open("A/MODULES.LOG", O_WRONLY|O_CREAT|O_APPEND, 0777);
307 if (fd >= 0)
308 {
309 lseek(fd, 0, SEEK_END);
310 write(fd, buf, strlen(buf));
311 close(fd);
312 }
313 }
314 }
315
316
317
318 static void module_log_hdr()
319 {
320 static int hdr_logged = 0;
321
322 if (conf.module_logging)
323 {
324 if (hdr_logged == 0)
325 {
326 hdr_logged = 1;
327
328 time_t datetime;
329 struct tm *ttm;
330 char buf[100];
331
332 datetime = time(NULL);
333 ttm = localtime(&datetime);
334
335 sprintf(buf, "Tick ,Op,Address ,Name (%04d:%02d:%02d %02d:%02d:%02d)\n", ttm->tm_year+1900, ttm->tm_mon+1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min, ttm->tm_sec);
336
337 module_writeline(buf);
338 }
339 }
340 }
341
342
343 void module_log_clear()
344 {
345 remove("A/MODULES.LOG");
346 }
347
348
349 static void module_log_load(const char *name, void* adr)
350 {
351 if (conf.module_logging)
352 {
353 char buf[100];
354 sprintf(buf,"%8d,LD,%08x,%s\n",get_tick_count(),adr,name);
355
356 module_log_hdr();
357 module_writeline(buf);
358 }
359 }
360
361
362 static void module_log_unload(char *name)
363 {
364 if (conf.module_logging)
365 {
366 char buf[100];
367 sprintf(buf,"%8d,UN, ,%s\n",get_tick_count(),name);
368
369 module_log_hdr();
370 module_writeline(buf);
371 }
372 }
373
374
375
376 static int bind_module(module_handler_t* hMod, void* module_lib)
377 {
378
379 if (module_lib == 0)
380 *hMod->lib = hMod->default_lib;
381 else
382 *hMod->lib = module_lib;
383
384 return 0;
385 }
386
387
388
389 static void module_unload_idx(int idx)
390 {
391 if ((idx >= 0) && (modules[idx].hdr != 0))
392 {
393
394 module_log_unload(modules[idx].hMod->name);
395
396
397 if (modules[idx].hdr->_module_info->lib->unloader)
398 modules[idx].hdr->_module_info->lib->unloader();
399
400
401 bind_module(modules[idx].hMod, 0);
402
403
404 free(modules[idx].hdr);
405 modules[idx].hdr = 0;
406 }
407 }
408
409
410 void module_unload(const char* name)
411 {
412
413 char path[60];
414 unsigned int hash = get_module_path(path, name);
415
416
417 module_unload_idx(module_find(hash));
418 }
419
420
421
422
423 static char* validate(ModuleInfo *mod_info, _version_t ver)
424 {
425 static char msg[50];
426
427 if ((mod_info->magicnum != MODULEINFO_V1_MAGICNUM) || (mod_info->sizeof_struct != sizeof(ModuleInfo)))
428 return "Malformed module info";
429
430 if (mod_info->chdk_required_branch && (mod_info->chdk_required_branch != CURRENT_CHDK_BRANCH))
431 return "require different CHDK branch";
432
433 if (mod_info->chdk_required_architecture != OPT_ARCHITECTURE)
434 return "wrong CHDK architecture";
435
436 if (mod_info->chdk_required_ver > CHDK_BUILD_NUM)
437 {
438 sprintf(msg, "require CHDK%05d", mod_info->chdk_required_ver);
439 return msg;
440 }
441
442 if (mod_info->chdk_required_platfid && (mod_info->chdk_required_platfid != (uint32_t)conf.platformid))
443 {
444 sprintf(msg, "require platfid %d", mod_info->chdk_required_platfid);
445 return msg;
446 }
447
448 if (!chk_api_version(mod_info->module_version, ver))
449 return "incorrect module version";
450
451 if (!chk_api_version((_version_t)CONF_VERSION, mod_info->conf_ver))
452 return "incorrect CONF version";
453
454 if (!chk_api_version((_version_t)CAM_SCREEN_VERSION, mod_info->cam_screen_ver))
455 return "incorrect CAM SCREEN version";
456
457 if (!chk_api_version((_version_t)CAM_SENSOR_VERSION, mod_info->cam_sensor_ver))
458 return "incorrect CAM SENSOR version";
459
460 if (!chk_api_version((_version_t)CAM_INFO_VERSION, mod_info->cam_info_ver))
461 return "incorrect CAM INFO version";
462
463 return 0;
464 }
465
466
467
468 static char* load_module_file(int fd, const char* name, int size, int bss_size, flat_hdr** flat_buf)
469 {
470 *flat_buf = (flat_hdr*)malloc(size+bss_size);
471 if (!*flat_buf)
472 return "malloc";
473
474 module_log_load(name, *flat_buf);
475
476 if (lseek(fd, 0, SEEK_SET) == 0)
477 {
478 if (b_read(fd, (char*)*flat_buf, size) == size)
479 {
480 memset((unsigned char*)(*flat_buf)+size, 0, bss_size);
481 return 0;
482 }
483 }
484
485
486 free(*flat_buf);
487 *flat_buf = 0;
488
489 return "read";
490 }
491
492
493
494 static char* link_module(int fd, flat_hdr* flat_buf)
495 {
496
497 int reloc_size = flat_buf->import_start - flat_buf->reloc_start;
498 int import_size = flat_buf->import_size;
499
500
501 int sz = (reloc_size > import_size) ? reloc_size : import_size;
502
503 if (!get_buffer(sz))
504 return "malloc";
505
506 if (!module_do_action(fd, flat_buf, flat_buf->reloc_start, reloc_size, module_do_relocations))
507 return "reloc error";
508
509 if (!module_do_action(fd, flat_buf, flat_buf->import_start, import_size, module_do_imports))
510 return "link error";
511
512 return 0;
513 }
514
515
516
517
518 flat_hdr* module_preload(const char *path, const char *name, _version_t ver)
519 {
520
521 int module_fd = b_open(path);
522 if (module_fd <= 0)
523 {
524 moduleload_error(name, "open error");
525 return 0;
526 }
527
528
529 flat_hdr flat;
530 b_read(module_fd, (char*)&flat, sizeof(flat));
531
532
533 char *msg = 0;
534
535
536 flat_hdr* flat_buf = 0;
537
538
539 if ((flat.rev == FLAT_VERSION) && (flat.magic == FLAT_MAGIC_NUMBER))
540 {
541
542 msg = load_module_file(module_fd, name, flat.reloc_start, flat.bss_size, &flat_buf);
543 if (msg == 0)
544 {
545
546 ModuleInfo *mod_info = flat_buf->_module_info = (ModuleInfo*)((unsigned int)flat_buf+flat_buf->_module_info_offset);
547
548
549 msg = validate(mod_info, ver);
550 if (msg == 0)
551 {
552
553 msg = link_module(module_fd, flat_buf);
554 }
555 }
556 }
557 else
558 msg = "bad magicnum";
559
560
561 b_close(module_fd);
562
563
564 if (msg)
565 {
566 if (flat_buf)
567 free(flat_buf);
568 moduleload_error(name, msg);
569 return 0;
570 }
571
572
573
574
575 dcache_clean_all();
576
577 icache_flush_all();
578
579
580 return flat_buf;
581 }
582
583
584
585
586 static int _module_load(module_handler_t* hMod)
587 {
588 int idx;
589
590
591 char path[60];
592 unsigned int hash = get_module_path(path, hMod->name);
593
594
595 idx = module_find(hash);
596 if (idx >= 0)
597 return idx;
598
599
600 *hMod->lib = hMod->default_lib;
601
602
603
604 static int isLoading = 0;
605 while (isLoading != 0) msleep(10);
606 isLoading = 1;
607
608
609 for (idx=0; idx<MAX_NUM_LOADED_MODULES && modules[idx].hdr; idx++) ;
610
611
612 if (idx == MAX_NUM_LOADED_MODULES)
613 {
614 moduleload_error(hMod->name, "too many modules loaded");
615 idx = -1;
616 }
617 else
618 {
619
620 flat_hdr* mod = module_preload(path, hMod->name, hMod->version);
621
622 if (mod != 0)
623 {
624
625 modules[idx].hdr = mod;
626 modules[idx].hName = hash;
627 modules[idx].hMod = hMod;
628
629 int bind_err = bind_module(hMod, mod->_module_info->lib);
630
631
632 if (!bind_err && mod->_module_info->lib->loader)
633 {
634 bind_err = mod->_module_info->lib->loader();
635 }
636
637
638 if (bind_err)
639 {
640 module_unload_idx(idx);
641 moduleload_error(hMod->name, "loader error");
642 idx = -1;
643 }
644 }
645 else
646 {
647
648 idx = -1;
649 }
650 }
651
652
653 isLoading = 0;
654
655 return idx;
656 }
657
658
659
660 int module_load(module_handler_t* hMod)
661 {
662
663 _module_load(hMod);
664
665
666 if (*hMod->lib && (*hMod->lib != hMod->default_lib))
667 {
668 return 1;
669 }
670
671
672 if (*hMod->lib == 0)
673 *hMod->lib = hMod->default_lib;
674
675
676 return 0;
677 }
678
679
680
681
682
683
684 #define MAX_SIMPLE_MODULE 4
685
686
687 static int default_run0();
688 static int default_run1();
689 static int default_run2();
690 static int default_run3();
691
692
693 static libsimple_sym default_librun[MAX_SIMPLE_MODULE] =
694 {
695 { { 0, 0, 0, 0, default_run0 } },
696 { { 0, 0, 0, 0, default_run1 } },
697 { { 0, 0, 0, 0, default_run2 } },
698 { { 0, 0, 0, 0, default_run3 } }
699 };
700 static libsimple_sym* librun[MAX_SIMPLE_MODULE] = { &default_librun[0], &default_librun[1], &default_librun[2], &default_librun[3] };
701
702
703
704 static char h_name[MAX_SIMPLE_MODULE][64];
705
706
707 static module_handler_t h_run[MAX_SIMPLE_MODULE] =
708 {
709 { (base_interface_t**)&librun[0], &default_librun[0].base, ANY_VERSION, h_name[0] },
710 { (base_interface_t**)&librun[1], &default_librun[1].base, ANY_VERSION, h_name[1] },
711 { (base_interface_t**)&librun[2], &default_librun[2].base, ANY_VERSION, h_name[2] },
712 { (base_interface_t**)&librun[3], &default_librun[3].base, ANY_VERSION, h_name[3] }
713 };
714
715
716 static void module_run_error(int err, char *name)
717 {
718 char buf[100];
719 sprintf(buf, lang_str(err), name);
720 gui_mbox_init(LANG_ERROR, (int)buf, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
721 }
722
723
724
725
726 static int default_run(int n)
727 {
728 if (module_load(&h_run[n]))
729 {
730 if ((*h_run[n].lib)->run)
731 {
732 return (*h_run[n].lib)->run();
733 }
734 else
735 {
736
737 module_run_error(LANG_MODULE_NOT_SIMPLE, h_run[n].name);
738
739 }
740 }
741
742 return -1;
743 }
744
745
746 static int default_run0() { return default_run(0); }
747 static int default_run1() { return default_run(1); }
748 static int default_run2() { return default_run(2); }
749 static int default_run3() { return default_run(3); }
750
751
752
753
754
755 int module_run(char* name)
756 {
757 int i;
758 for (i=0; i<MAX_SIMPLE_MODULE; i++)
759 {
760
761 if (*h_run[i].lib != h_run[i].default_lib)
762 {
763 if (namecmp(name, h_run[i].name))
764 {
765
766 return (*h_run[i].lib)->run();
767 }
768 }
769 }
770 for (i=0; i<MAX_SIMPLE_MODULE; i++)
771 {
772
773 if (*h_run[i].lib == h_run[i].default_lib)
774 {
775
776 strcpy(h_run[i].name, name);
777 return (*h_run[i].lib)->run();
778 }
779 }
780
781
782 module_run_error(LANG_MODULE_NO_SPACE, name);
783
784 return -1;
785 }
786
787
788
789
790
791
792 void module_exit_alt()
793 {
794 int idx;
795
796 for (idx=MAX_NUM_LOADED_MODULES-1; idx>=0; idx--)
797 {
798 if (modules[idx].hdr && modules[idx].hdr->_module_info->lib->exit_alt)
799 {
800
801 modules[idx].hdr->_module_info->lib->exit_alt();
802 }
803 }
804 }
805
806
807
808
809 void module_tick_unloader()
810 {
811 int idx;
812
813 for (idx=MAX_NUM_LOADED_MODULES-1; idx>=0; idx--)
814 {
815 if (modules[idx].hdr && modules[idx].hdr->_module_info->lib->can_unload)
816 {
817
818 if (modules[idx].hdr->_module_info->lib->can_unload())
819 module_unload_idx(idx);
820 }
821 }
822 }
823
824
825
826
827
828 module_entry* module_get_adr(unsigned int idx)
829 {
830 if (idx < MAX_NUM_LOADED_MODULES)
831 if (modules[idx].hdr)
832 return &modules[idx];
833 return 0;
834 }
835
836
837
838 void get_module_info(const char *name, ModuleInfo *mi, char *modName, int modNameLen)
839 {
840 memset(mi, 0, sizeof(ModuleInfo));
841 if (modName)
842 modName[0] = 0;
843
844
845 char path[60];
846 get_module_path(path, name);
847
848
849 int fd = open(path, O_RDONLY, 0777);
850 if (fd < 0)
851 return;
852
853
854 flat_hdr flat;
855 read(fd, (char*)&flat, sizeof(flat_hdr));
856
857
858 if ((flat.rev == FLAT_VERSION) && (flat.magic == FLAT_MAGIC_NUMBER))
859 {
860 lseek(fd, flat._module_info_offset, SEEK_SET);
861 read(fd, mi, sizeof(ModuleInfo));
862
863 if ((mi->moduleName >= 0) && modName)
864 {
865
866 lseek(fd, mi->moduleName, SEEK_SET);
867 read(fd, modName, modNameLen-1);
868 modName[modNameLen-1] = 0;
869 }
870 }
871
872 close(fd);
873 }
874
875