dst[ndst] = src[i];
//Reset the index value of the symbol name in mod->core_strtab
dst[ndst++].st_name = s - mod->core_strtab;
//Copy the symbol name to mod->module_core + info->stroffs
s += strlcpy(s, &mod->strtab[src[i].st_name],KSYM_NAME_LEN) + 1;
}
}
mod->core_num_syms = ndst; //Number of symbols
}
static int complete_formation(struct module *mod, struct load_info *info)
{
int err;
mutex_lock(&module_mutex);
// Check if there is any redefinition symbol
err = verify_export_symbols(mod);
if (err < 0)
goto out;
//Module bug related operations
module_bug_finalize(info->hdr, info->sechdrs, mod);
//Set the status of the module
mod->state = MODULE_STATE_COMING;
out:
mutex_unlock(&module_mutex);
return err;
}
static int verify_export_symbols(struct module *mod)
{
unsigned int i;
struct module *owner;
const struct kernel_symbol *s;
struct {
const struct kernel_symbol *sym;
unsigned int num;
} arr[] = {
{ mod->syms, mod->num_syms },
{ mod->gpl_syms, mod->num_gpl_syms },
{ mod->gpl_future_syms, mod->num_gpl_future_syms },
#ifdef CONFIG_UNUSED_SYMBOLS
{ mod->unused_syms, mod->num_unused_syms },
{ mod->unused_gpl_syms, mod->num_unused_gpl_syms },
#endif
};
//Traverse the symbols in the module and check in the kernel whether they have been exported. If the symbol has been exported, the famous error "exports duplicate symbol" is given.
for (i = 0; i < ARRAY_SIZE(arr); i++) {
for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
if (find_symbol(s->name, &owner, NULL, true, false)) {
printk(KERN_ERR "%s: exports duplicate symbol %s"" (owned by %s)n",mod->name, s->name, module_name(owner));
return -ENOEXEC;
}
}
}
return 0;
}
static int do_init_module(struct module *mod)
{
int ret = 0;
current->flags &= ~PF_USED_ASYNC;
// Kernel notification
blocking_notifier_call_chain(&module_notify_list,MODULE_STATE_COMING, mod);
//Set RO and NX regions for core
set_section_ro_nx(mod->module_core,mod->core_text_size,mod->core_ro_size,mod->core_size);
//Set RO and NX regions for init
set_section_ro_nx(mod->module_init,mod->init_text_size,mod->init_ro_size,mod->init_size);
//Call the module constructor
do_mod_ctors(mod);
//Start the module
if (mod->init != NULL)
ret = do_one_initcall(mod->init);
if (ret < 0) {
/* Init routine failed: abort. Try to protect us from buggy refcounters. */
mod->state = MODULE_STATE_GOING;
synchronize_sched();
module_put(mod);
blocking_notifier_call_chain(&module_notify_list,MODULE_STATE_GOING, mod);
free_module(mod);
wake_up_all(&module_wq);
return ret;
}
if (ret > 0) {
printk(KERN_WARNING"%s: '%s'->init suspiciously returned %d, it should follow 0/-E conventionn""%s: loading module anyway...n",__func__,mod->name, ret, __func__);
dump_stack();
}
//Module initialization completed, change status, notify the kernel
mod->state = MODULE_STATE_LIVE;
blocking_notifier_call_chain(&module_notify_list,MODULE_STATE_LIVE, mod);
if (current->flags & PF_USED_ASYNC)
async_synchronize_full();
mutex_lock(&module_mutex);
/* Drop initial reference. */
module_put(mod);
rim_init_extable(mod);
#ifdef CONFIG_KALLSYMS
mod->num_symtab = mod->core_num_syms;
mod->symtab = mod->core_symtab;
mod->strtab = mod->core_strtab;
#endif
//Release the initialization space, which is only valid during initialization. After initialization, recycle resources and clear
unset_module_init_ro_nx(mod);
module_free(mod, mod->module_init);
mod->module_init = NULL;
mod->init_size = 0;
mod->init_ro_size = 0;
mod->init_text_size = 0;
mutex_unlock(&module_mutex);
wake_up_all(&module_wq);
return 0;
}
int __init_or_module do_one_initcall(initcall_t fn)
{
int count = preempt_count();
int ret;
char msgbuf[64];
if (initcall_debug)
ret = do_one_initcall_debug(fn);
else
ret = fn(); //Execute the init_module function of the module
msgbuf[0] = 0;
if (preempt_count() != count) {
sprintf(msgbuf, "preemption imbalance ");
preempt_count() = count;
}
if (irqs_disabled()) {
strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
local_irq_enable();
}
WARN(msgbuf[0], "initcall %pF returned with %sn", fn, msgbuf);
return ret;
}
Previous article:Linux driver to create a hello module
Next article:S3C2440 Watchdog Timer Principle
Recommended ReadingLatest update time:2024-11-16 20:32
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- What kind of long distance wireless transmission equipment is there?
- 【Tuya BK7231N】In-depth analysis of sample code
- The sipeed team will provide developers with free MAXI development boards
- CircuitPython-enabled electronic cat (MeowMeow)
- Research on Several Issues of Portable Image Acquisition System Based on ARM and FPGA
- Please give me some advice!
- Analysis of the switch input circuit composed of four diodes
- Analysis of common problems in TMS320C2000 projects?
- Clock chip problem
- 18 Ways to Draw PCB Routes