接下里的函数
void bs_set_timestamp(enum bs_entry bs_id)
{
addr_t bs_imem = get_bs_info_addr();
uint32_t clk_count = 0;
if(bs_imem) {
if (bs_id >= BS_MAX) {
dprintf(CRITICAL, "bad bs id: %u, max: %u\n", bs_id, BS_MAX);
ASSERT(0);
}
if (bs_id == BS_KERNEL_LOAD_START) {
kernel_load_start = platform_get_sclk_count();
return;
}
if(bs_id == BS_KERNEL_LOAD_DONE){
clk_count = platform_get_sclk_count();
if(clk_count){
writel(clk_count - kernel_load_start,
bs_imem + (sizeof(uint32_t) * BS_KERNEL_LOAD_TIME));
}
}
else{
clk_count = platform_get_sclk_count();
if(clk_count){
writel(clk_count,
bs_imem + (sizeof(uint32_t) * bs_id));
}
}
}
}
这个函数不干啥事
接下来的函数很牛
extern void *__ctor_list;
extern void *__ctor_end;
static void call_constructors(void)
{
void **ctor;
ctor = &__ctor_list;
while(ctor != &__ctor_end) {
void (*func)(void);
func = (void (*)())*ctor;
func();
ctor++;
}
}
这个才是c语言的精华所在,首先__ctor_list已经是一个void类型指针,取指针的地址当然要用**才行。然后
(void (*)( )) ,是一个返回值为void,参数为空的函数指针原型。
void heap_init(void)
{
LTRACE_ENTRY;
// set the heap range
theheap.base = (void *)HEAP_START; //这么做是方便以后这个base可以转换成任何类型的指针
//struct free_heap_chunk *chunk = (struct free_heap_chunk *)ptr;
theheap.len = HEAP_LEN;
LTRACEF("base %p size %zd bytes\n", theheap.base, theheap.len);
// initialize the free list
list_initialize(&theheap.free_list);
// create an initial free chunk
heap_insert_free_chunk(heap_create_free_chunk(theheap.base, theheap.len));
// dump heap info
// heap_dump();
// dprintf(INFO, "running heap tests\n");
// heap_test();
}
接下来看
#define __stack_chk_guard_setup() do { __stack_chk_guard = get_canary(); } while(0)
经典的宏定义,内核之中比比皆是啊
还有一个很经典的
static event_t dpc_event;
static int dpc_thread_routine(void *arg);
void dpc_init(void)
{
event_init(&dpc_event, false, 0); //初始化event
thread_resume(thread_create("dpc", &dpc_thread_routine, NULL, DPC_PRIORITY, DEFAULT_STACK_SIZE)); //跑一个线程
}
status_t dpc_queue(dpc_callback cb, void *arg, uint flags) //被别人调用
{
struct dpc *dpc;
dpc = malloc(sizeof(struct dpc));
dpc->cb = cb;
dpc->arg = arg;
enter_critical_section();
list_add_tail(&dpc_list, &dpc->node);
event_signal(&dpc_event, (flags & DPC_FLAG_NORESCHED) ? false : true);
exit_critical_section();
return NO_ERROR;
}
static int dpc_thread_routine(void *arg)
{
for (;;) {
event_wait(&dpc_event); //等待event发生
enter_critical_section();
struct dpc *dpc = list_remove_head_type(&dpc_list, struct dpc, node);
if (!dpc)
event_unsignal(&dpc_event);
exit_critical_section();
if (dpc) {
// dprintf("dpc calling %p, arg %p\n", dpc->cb, dpc->arg);
dpc->cb(dpc->arg);
free(dpc);
}
}
return 0;
}
看看
status_t event_wait_timeout(event_t *e, time_t timeout)
{
status_t ret = NO_ERROR;
enter_critical_section();
#if EVENT_CHECK
ASSERT(e->magic == EVENT_MAGIC);
#endif
if (e->signalled) {
/* signalled, we're going to fall through */
if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) { //如果flag是1则将signalled设为false
/* autounsignal flag lets one thread fall through before unsignalling */
e->signalled = false;
}
} else {
/* unsignalled, block here */
ret = wait_queue_block(&e->wait, timeout); //不然就继续等待
if (ret < 0)
goto err;
}
err:
exit_critical_section();
return ret;
}
还有
status_t event_signal(event_t *e, bool reschedule)
{
enter_critical_section();
#if EVENT_CHECK
ASSERT(e->magic == EVENT_MAGIC);
#endif
if (!e->signalled) { //init的时候signal是false,所以跑进来了
if (e->flags & EVENT_FLAG_AUTOUNSIGNAL) { //<span style="font-family: Helvetica, Tahoma, Arial, sans-serif;">EVENT_FLAG_AUTOUNSIGNAL是1,所以跑不进来</span>
/* try to release one thread and leave unsignalled if successful */
if (wait_queue_wake_one(&e->wait, reschedule, NO_ERROR) <= 0) {
/*
* if we didn't actually find a thread to wake up, go to
* signalled state and let the next call to event_wait
* unsignal the event.
*/
e->signalled = true;
}
} else {
/* release all threads and remain signalled */
e->signalled = true; //让signal变成true
wait_queue_wake_all(&e->wait, reschedule, NO_ERROR);
}
}
exit_critical_section();
return NO_ERROR;
} //这个函数执行完之后signalled肯定变成true,所以event_wait(&dpc_event);里的才能执行而不是始终阻塞