diff --git a/include/kernel/system.h b/include/kernel/system.h index b583ff46..e7e4ddf7 100644 --- a/include/kernel/system.h +++ b/include/kernel/system.h @@ -14,7 +14,7 @@ // build settings -#define KERNEL_VERSION "1.3.1c" +#define KERNEL_VERSION "1.3.2" #define KERNEL_EDITING "generic" #define PROCESS_MAX 200 // max process count diff --git a/kernel/kpart/modload.c b/kernel/kpart/modload.c index bff8a1b9..e1487ce4 100644 --- a/kernel/kpart/modload.c +++ b/kernel/kpart/modload.c @@ -16,6 +16,9 @@ #include #include +#define MODLOAD_FARRAY_MAGIC 0xF3A3C4D4 +#define MODLOAD_FARRAY_NAME "__module_func_array" + uint32_t *g_mod_funcs[256]; /* g_mod_funcs[n] layout: @@ -94,57 +97,51 @@ static uint32_t *i_mod_read_funcs(uint8_t *file, uint8_t *mem) { return NULL; // read a first time to get function count - uint32_t func_count = 0; Elf32_Sym *symbol_table = (Elf32_Sym *) (file + sym_sh->sh_offset); char *strtab = (char *) (file + shdr[sym_sh->sh_link].sh_offset); + uint32_t *func_array = NULL; + uint32_t func_count = 0; + + // search for the function array for (uint32_t i = 0; i < sym_sh->sh_size / sizeof(Elf32_Sym); i++) { - if (((Elf32_Sym *) symbol_table + i)->st_info == 0x12) - func_count++; + Elf32_Sym *symbol = symbol_table + i; + + if (symbol->st_name && str_cmp(strtab + symbol->st_name, MODLOAD_FARRAY_NAME) == 0) { + func_array = (uint32_t *) (mem + symbol->st_value); + if (func_array[0] != MODLOAD_FARRAY_MAGIC) + return NULL; + func_count = symbol->st_size / sizeof(uint32_t) - 1; + break; + } } - if (func_count == 0) + if (func_array == NULL) return NULL; // allocate the address list uint32_t *addr_list = mem_alloc((func_count + 4) * sizeof(uint32_t), SNOW_MOD, 0); addr_list[0] = (uint32_t) mem; addr_list[1] = func_count; - addr_list[2] = 0; - addr_list[3] = 0; - - func_count = 4; + addr_list[2] = 0; // __init address + addr_list[3] = 0; // __fini address for (uint32_t i = 0; i < sym_sh->sh_size / sizeof(Elf32_Sym); i++) { Elf32_Sym *symbol = symbol_table + i; - if (symbol->st_info != 0x12) + if (symbol->st_info != 0x12 || !symbol->st_name) continue; - if (symbol->st_name) { - if (str_cmp(strtab + symbol->st_name, "__init") == 0) { - addr_list[2] = symbol->st_value + (uint32_t) mem; - continue; - } + else if (str_cmp(strtab + symbol->st_name, "__init") == 0) + addr_list[2] = symbol->st_value + (uint32_t) mem; - if (str_cmp(strtab + symbol->st_name, "__fini") == 0) { - addr_list[3] = symbol->st_value + (uint32_t) mem; - continue; - } - } - - addr_list[func_count++] = symbol->st_value + (uint32_t) mem; + else if (str_cmp(strtab + symbol->st_name, "__fini") == 0) + addr_list[3] = symbol->st_value + (uint32_t) mem; } - // sort the functions by address - for (uint32_t i = 4; i < func_count; i++) { - for (uint32_t j = i + 1; j < func_count; j++) { - if (addr_list[i] > addr_list[j]) { - uint32_t tmp = addr_list[i]; - addr_list[i] = addr_list[j]; - addr_list[j] = tmp; - } - } + // copy function addresses + for (uint32_t i = 0; i < func_count; i++) { + addr_list[i + 4] = func_array[i + 1]; } return addr_list; diff --git a/tools/maketool.py b/tools/maketool.py index 4a850226..82813a16 100644 --- a/tools/maketool.py +++ b/tools/maketool.py @@ -290,14 +290,12 @@ def build_c_to_sys(name, fname, stt_list): print_and_exec(f"rm {fname}.o") total -= 1 - def build_c_to_mod(name, fname, stt_list): + def build_c_to_mod(name, fname): global total print_info_line(name) - required_libs = get_required_libs(name, stt_list) print_and_exec(f"{CC} -c {name} -o {fname}.o {MOD_FLAGS}") - print_and_exec(f"{SHRD} -L {OUT_DIR}/zlibs -o {fname}.pkm {fname}.o " + - ' '.join([f'-l{lib[3:]}' for lib in required_libs])) + print_and_exec(f"{SHRD} -o {fname}.pkm {fname}.o") print_and_exec(f"rm {fname}.o") total -= 1 @@ -313,13 +311,18 @@ def build_c_to_elf(name, fname, liblist): print_and_exec(f"rm {fname}.o") total -= 1 - def build_c_to_obj(name, fname, is_lib): + def build_c_to_obj(name, fname, dest): global total print_info_line(name) - if is_lib: + if dest == "lib": flags = ZLIB_FLAGS - else: + elif dest == "exe": flags = ZAPP_FLAGS + f" -I {'/'.join(name.split('/')[0:3])}/{INCLUDE_DIR}" + elif dest == "mod": + flags = MOD_FLAGS + f" -I {'/'.join(name.split('/')[0:3])}/{INCLUDE_DIR}" + else: + cprint(COLOR_EROR, f"unknown type '{dest}' for build_c_to_obj") + os._exit(1) print_and_exec(f"{CC} {flags} -c {name} -o {fname}.o") total -= 1 @@ -342,9 +345,22 @@ def link_multifile_elf(name, libs_name): f"-o {OUT_DIR}/{name}.elf {OUT_DIR}/make/entry_elf.o {' '.join(objs)} -lc " + ' '.join([f'-l{lib[3:]}' for lib in required_libs])) + def link_multifile_lib(name): + objs = files_in_dir_rec(f"{OUT_DIR}/zlibs/{name}", ".o") + print_info_line(f"[link] zlibs/{name}.so") + print_and_exec(f"{SHRD} -o {OUT_DIR}/zlibs/{name}.so {' '.join(objs)}" + + (f" -L{OUT_DIR}/zlibs -lc" if name != "libc" else "")) + + def link_multifile_mod(name): + objs = files_in_dir_rec(f"{OUT_DIR}/zlibs/{ZLIBS_MOD}/{name}", ".o") + print_info_line(f"[link] zlibs/{ZLIBS_MOD}/{name}.pkm") + print_and_exec(f"{SHRD} -o {OUT_DIR}/zlibs/{ZLIBS_MOD}/{name}.pkm {' '.join(objs)}") + + # detect zlibs lib_build_list = [] mod_build_list = [] + mmf_build_list = [] # multi file module stt_build_list = [] for dir_name in os.listdir(ZLIBS_DIR): @@ -353,7 +369,6 @@ def link_multifile_elf(name, libs_name): exit(1) if dir_name == ZLIBS_MOD: - mod_build_list.extend(files_in_dir_rec(f"{ZLIBS_DIR}/{dir_name}", ".c")) continue if dir_name == ZLIBS_STT: @@ -362,6 +377,14 @@ def link_multifile_elf(name, libs_name): lib_build_list.extend(files_in_dir_rec(f"{ZLIBS_DIR}/{dir_name}", ".c")) + for name in os.listdir(f"{ZLIBS_DIR}/{ZLIBS_MOD}"): + if not os.path.isdir(f"{ZLIBS_DIR}/{ZLIBS_MOD}/{name}"): + if not name.endswith(".c"): + continue + mod_build_list.append(f"{ZLIBS_DIR}/{ZLIBS_MOD}/{name}") + else: + mmf_build_list.extend(files_in_dir_rec(f"{ZLIBS_DIR}/{ZLIBS_MOD}/{name}", ".c")) + # detect zapps bin_build_list = [] dir_build_list = [] @@ -418,6 +441,7 @@ def link_multifile_elf(name, libs_name): total_elf = len(elf_build_list) total_lib = len(lib_build_list) total_mod = len(mod_build_list) + total_mmf = len(mmf_build_list) total_stt = len(stt_build_list) elf_build_list = [file for file in elf_build_list if not file1_newer( @@ -437,15 +461,20 @@ def link_multifile_elf(name, libs_name): f"{OUT_DIR}/{file.replace('.c', '.o')}", file) and file1_newer( f"{OUT_DIR}/{'/'.join(file.split('/')[0:3])}.elf", file))] - cprint(COLOR_INFO, f"| kernel mods: {len(mod_build_list)} / {total_mod}") - cprint(COLOR_INFO, f"| shared libs: {len(lib_build_list)} / {total_lib}") - cprint(COLOR_INFO, f"| static libs: {len(stt_build_list)} / {total_stt}") - cprint(COLOR_INFO, f"| system bins: {len(bin_build_list)} / {total_bin}") - cprint(COLOR_INFO, f"| single elfs: {len(elf_build_list)} / {total_elf}") - cprint(COLOR_INFO, f"| multi files: {len(dir_build_list)} / {total_dir}") + mmf_build_list = [file for file in mmf_build_list if not (file1_newer( + f"{OUT_DIR}/{file.replace('.c', '.o')}", file) and file1_newer( + f"{OUT_DIR}/zlibs/{ZLIBS_MOD}/{file.split('/')[2]}.pkm", file))] + + cprint(COLOR_INFO, f"| single file pkm: {len(mod_build_list)} / {total_mod}") + cprint(COLOR_INFO, f"| multi file pkm: {len(mmf_build_list)} / {total_mmf}") + cprint(COLOR_INFO, f"| shared lib: {len(lib_build_list)} / {total_lib}") + cprint(COLOR_INFO, f"| static lib: {len(stt_build_list)} / {total_stt}") + cprint(COLOR_INFO, f"| single file exe: {len(elf_build_list)} / {total_elf}") + cprint(COLOR_INFO, f"| multi file exe: {len(dir_build_list)} / {total_dir}") + cprint(COLOR_INFO, f"| static exe: {len(bin_build_list)} / {total_bin}") # create directories - for file in elf_build_list + bin_build_list + lib_build_list + mod_build_list + dir_build_list: + for file in elf_build_list + bin_build_list + lib_build_list + mod_build_list + dir_build_list + mmf_build_list: dir_name = file[:max([max(x for x in range(len(file)) if file[x] == "/")])] if not os.path.exists(f"{OUT_DIR}/{dir_name}"): @@ -457,7 +486,7 @@ def link_multifile_elf(name, libs_name): for name in lib_build_list: fname = f"{OUT_DIR}/{remove_ext(name)}" - threading.Thread(target = build_c_to_obj, args=(name, fname, 1)).start() + threading.Thread(target = build_c_to_obj, args=(name, fname, "lib")).start() for name in stt_build_list: fname = f"{OUT_DIR}/{ZLIBS_DIR}/{remove_ext(name.split('/')[-1])}" @@ -475,12 +504,9 @@ def link_multifile_elf(name, libs_name): to_link.insert(0, "libc") for name in to_link: - objs = files_in_dir_rec(f"{OUT_DIR}/zlibs/{name}", ".o") - print_info_line(f"[link] zlibs/{name}.so") - print_and_exec(f"{SHRD} -o {OUT_DIR}/zlibs/{name}.so {' '.join(objs)}" + - (f" -L{OUT_DIR}/zlibs -lc" if name != "libc" else "")) + link_multifile_lib(name) - total = len(elf_build_list) + len(bin_build_list) + len(mod_build_list) + len(dir_build_list) + total = len(elf_build_list) + len(bin_build_list) + len(mod_build_list) + len(dir_build_list) + len(mmf_build_list) # get .so files libs_name = [e[:-3] for e in files_in_dir(f"{OUT_DIR}/zlibs", ".so")] @@ -488,7 +514,11 @@ def link_multifile_elf(name, libs_name): for name in mod_build_list: fname = f"{OUT_DIR}/{remove_ext(name)}" - threading.Thread(target = build_c_to_mod, args=(name, fname, stts_name)).start() + threading.Thread(target = build_c_to_mod, args=(name, fname)).start() + + for name in mmf_build_list: + fname = f"{OUT_DIR}/{remove_ext(name)}" + threading.Thread(target = build_c_to_obj, args=(name, fname, "mod")).start() for name in elf_build_list: fname = f"{OUT_DIR}/{remove_ext(name)}" @@ -500,7 +530,7 @@ def link_multifile_elf(name, libs_name): for name in dir_build_list: fname = f"{OUT_DIR}/{remove_ext(name)}" - threading.Thread(target = build_c_to_obj, args=(name, fname, 0)).start() + threading.Thread(target = build_c_to_obj, args=(name, fname, "exe")).start() while total: # wait for all threads to finish @@ -510,6 +540,10 @@ def link_multifile_elf(name, libs_name): for name in list(set(["/".join(name.split("/")[0:3]) for name in dir_build_list])): link_multifile_elf(name, libs_name + stts_name) + # linking multi file mods + for name in list(set([name.split("/")[2] for name in mmf_build_list])): + link_multifile_mod(name) + def make_iso(force = False, more_option = False): elf_image() gen_disk(False) @@ -622,9 +656,9 @@ def gen_disk(force=True, with_src=False): if isinstance(HDD_MAP[dir_name], str): if dir_name == "lib": - print_and_exec(f"cp -r {HDD_MAP[dir_name]}/*.* " + ' '.join([f'{HDD_MAP[dir_name]}/{file}' - for file in os.listdir(HDD_MAP[dir_name]) if not file.startswith('lib') - ]) + f" {OUT_DIR}/disk/{dir_name}") + os.makedirs(f"{OUT_DIR}/disk/{dir_name}/{ZLIBS_MOD}") + print_and_exec(f"cp -r {HDD_MAP[dir_name]}/*.* {OUT_DIR}/disk/{dir_name}") + print_and_exec(f"cp -r {HDD_MAP[dir_name]}/{ZLIBS_MOD}/*.* {OUT_DIR}/disk/{dir_name}/modules") elif dir_name == "bin": for elm in os.listdir(HDD_MAP[dir_name]): diff --git a/zapps/f/olivine.c b/zapps/f/olivine.c index f930d3ac..839d38d1 100644 --- a/zapps/f/olivine.c +++ b/zapps/f/olivine.c @@ -14,7 +14,7 @@ #include #include -#define OLV_VERSION "1.9.5" +#define OLV_VERSION "1.9.6" #define BUILD_TARGET 0 // 0 auto - 1 minimal - 2 unix @@ -2033,6 +2033,7 @@ char *if_fstat(char **input) { puts("Usage: fstat [option] \n" "Options:\n" " -d check if path is a directory\n" + " -e check if path exists\n" " -h display this help\n" " -f check if path is a file\n" " -m last modification time\n" @@ -2040,6 +2041,8 @@ char *if_fstat(char **input) { " -s size of the file in bytes" ); break; + case 'e': + return exists ? strdup("1") : strdup("0"); case 'd': return (exists && S_ISDIR(st.st_mode)) ? strdup("1") : strdup("0"); case 'f': diff --git a/zapps/x/rosemary.c b/zapps/x/rosemary.c index ad99ed99..d4e3babc 100644 --- a/zapps/x/rosemary.c +++ b/zapps/x/rosemary.c @@ -69,7 +69,7 @@ int print_load_status(int i) { int error_code = syscall_mod_load(mod->path, mod->id); - if (error_code > 0) { + if (error_code >= 0) { syscall_kprint("\e[1A\e[37m[\e[92m OK \e[37m]\e[0m\n"); return 0; } else if (error_code == -7) { diff --git a/zlibs/modules/ata.c b/zlibs/modules/ata.c index 8ff5b73e..85810529 100644 --- a/zlibs/modules/ata.c +++ b/zlibs/modules/ata.c @@ -156,3 +156,8 @@ int __init(void) { return 0; } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + // no functions exported +}; diff --git a/zlibs/modules/devio.c b/zlibs/modules/devio.c index 51d5144a..34666ab5 100644 --- a/zlibs/modules/devio.c +++ b/zlibs/modules/devio.c @@ -207,3 +207,8 @@ int __init(void) { setup_afft("userial", dev_userial_r, dev_userial_w, NULL) ); } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + // no functions exported +}; diff --git a/zlibs/modules/filesys.c b/zlibs/modules/filesys.c index 175fd72a..a44075c4 100644 --- a/zlibs/modules/filesys.c +++ b/zlibs/modules/filesys.c @@ -720,3 +720,25 @@ uint32_t *fu_get_vdisk_info(void) { return ret; } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + fu_is_dir, + fu_dir_get_size, + fu_dir_get_elm, + fu_dir_get_content, + fu_add_to_dir, + fu_remove_from_dir, + fu_dir_create, + fu_is_file, + fu_file_set_size, + fu_file_get_size, + fu_file_create, + fu_file_read, + fu_file_write, + fu_is_afft, + fu_afft_create, + fu_afft_get_id, + fu_path_to_sid, + fu_get_vdisk_info +}; diff --git a/zlibs/modules/fmopen.c b/zlibs/modules/fmopen.c index d77d23a8..96317a37 100644 --- a/zlibs/modules/fmopen.c +++ b/zlibs/modules/fmopen.c @@ -648,3 +648,21 @@ int __init(void) { fm_reopen(2, "/dev/kterm", O_WRONLY) < 0 ); } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + fm_close, + fm_reopen, + fm_pread, + fm_pwrite, + fm_lseek, + fm_dup2, + fm_dup, + fm_pipe, + fm_isafft, + fm_isfile, + fm_fcntl, + fm_get_sid, + fm_get_path, + fm_declare_child +}; diff --git a/zlibs/modules/hdaudio.c b/zlibs/modules/hdaudio.c index 8cfb2e45..5fc1b071 100644 --- a/zlibs/modules/hdaudio.c +++ b/zlibs/modules/hdaudio.c @@ -1243,3 +1243,16 @@ void hda_stop_sound() { uint32_t hda_get_stream_position() { return mmio_ind(g_hda.output_stream_base + 0x04); } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + hda_map_memory, + hda_is_headphone_connected, + hda_set_volume, + hda_check_headphone_connection_change, + hda_is_supported_channel_size, + hda_is_supported_sample_rate, + hda_play_pcm_data, + hda_stop_sound, + hda_get_stream_position +}; diff --git a/zlibs/modules/panda.c b/zlibs/modules/panda.c index 8f4161b7..6e9f5328 100644 --- a/zlibs/modules/panda.c +++ b/zlibs/modules/panda.c @@ -688,7 +688,7 @@ void panda_screen_restore(void *data) { draw_cursor(0); } -void panda_screen_kfree(void *data) { +void panda_screen_free(void *data) { panda_global_t *panda = (panda_global_t *) data; if (!panda) return; @@ -779,3 +779,18 @@ int __init(void) { return (setup_afft("panda", dev_panda_w) || setup_afft("pander", dev_pander_w)); } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + panda_print_char, + panda_print_raw, + panda_print_string, + panda_sync_start, + panda_get_size, + panda_get_cursor, + panda_draw_cursor, + panda_change_font, + panda_screen_backup, + panda_screen_restore, + panda_screen_free, +}; diff --git a/zlibs/modules/profan.c b/zlibs/modules/profan.c index 1ef243e8..45c3b538 100644 --- a/zlibs/modules/profan.c +++ b/zlibs/modules/profan.c @@ -551,3 +551,11 @@ int run_ifexist(runtime_args_t *args, int *pid_ptr) { return ret; } + +void *__module_func_array[] = { + (void *) 0xF3A3C4D4, // magic + profan_kb_load_map, + profan_kb_get_char, + profan_input_keyboard, + run_ifexist +};