移植u-boot到mini2440--board_init_r 分析

1> 首先调用 static int initr_reloc,设置 标志重定位已经完成,malloc已经初始化。

static int initr_reloc(void)
{
        /* tell others: relocation done */
        gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
        return 0;
}

2> initr_caches 调用 函数__weak void enable_caches(void),这个函数没有实质性工作,需要自己定义板级函数

3> initr_reloc_global_data

monitor_flash_len = _end - __image_copy_start;

这里是求出 u-boot 映像占用的flash 大小,bss因为是未初始化的变量,不占用flash空间。

4> initr_barrier 空函数

5> initr_malloc 初始化堆内存

6> tdio_init_tables –> 调用 INIT_LIST_HEAD 初始化 stdio_dev 结构体的 list 成员。

7> initr_serial –> serial_initialize (drivers/serial/serial.c)
  在源文件中可以看到 这个函数调用了很多串口初始化的函数。但是在反汇编文件中看到它所调用的大部分都是空函数 amirix_serial_initialize 有效的函数调用只有一个 s3c24xx_serial_initialize

void s3c24xx_serial_initialize(void)
{
        serial_register(&s3c24xx_serial0_device);
        serial_register(&s3c24xx_serial1_device);
        serial_register(&s3c24xx_serial2_device);
}
void serial_register(struct serial_device *dev)
{
        dev->next = serial_devices;
        serial_devices = dev;
}

8> stdio_add_devices 这个函数又调用了2个函数:

drv_system_init ();
serial_stdio_init ()
static void drv_system_init (void)
{
        struct stdio_dev dev;

        memset (&dev, 0, sizeof (dev));

        strcpy (dev.name, "serial");
        dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
        dev.putc = stdio_serial_putc;
        dev.puts = stdio_serial_puts;
        dev.getc = stdio_serial_getc;
        dev.tstc = stdio_serial_tstc;
        stdio_register (&dev);
}

  注意这里是 stdio_register 跟上面的 serial_register 还不一样。

/** * serial_stdio_init() - Register serial ports with STDIO core * * This function generates a proxy driver for each serial port driver. * These proxy drivers then register with the STDIO core, making the * serial drivers available as STDIO devices. */
void serial_stdio_init(void)
{
        struct stdio_dev dev;
        struct serial_device *s = serial_devices;

        while (s) {
                memset(&dev, 0, sizeof(dev));

                strcpy(dev.name, s->name);
                dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;

                dev.start = serial_stub_start;
                dev.stop = serial_stub_stop;
                dev.putc = serial_stub_putc;
                dev.puts = serial_stub_puts;
                dev.getc = serial_stub_getc;
                dev.tstc = serial_stub_tstc;
                dev.priv = s;

                stdio_register(&dev);

                s = s->next;
        }
}

  这里把 initr_serial 函数注册的所有 serial_deviceserial_stub_xxx 系列函数关联起来,并且调用 stdio_register

9> console_init_r 调用了

inputdev = search_device(DEV_FLAGS_INPUT, "serial");
outputdev = search_device(DEV_FLAGS_OUTPUT, "serial");
errdev = search_device(DEV_FLAGS_OUTPUT, "serial");

  分别获取 标准输入,输出,错误设备,参数为 “serial” 。通过分析这里可知道它们都是前面通过drv_system_init ()注册的设备。

然后又调用

console_doenv(stdout, outputdev);
console_doenv(stderr, errdev);
console_doenv(stdin, inputdev);

  把设备与句柄绑定。
  最后设置标志,意味着设备初始化完成。

gd->flags |= GD_FLG_DEVINIT;    /* device initialization completed */

至于printf 执行流由于变动不大可以参考别人写的博文。

你可能感兴趣的:(串口,移植,u-boot,board-init)