您的位置:首页 > 其它

移植uboot第二步:分析uboot

2016-08-10 15:03 337 查看
1.在make的过程中,最后会显示链接文件,如下

UNDEF_SYM=`arm-linux-objdump -x board/samsung/smdk2410/libsmdk2410.o api/libapi.o arch/arm/cpu/arm920t/libarm920t.o arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.o arch/arm/lib/libarm.o common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/eth/libusb_eth.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/usb/ulpi/libusb_ulpi.o drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o post/libpost.o | sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`; cd /work/system/u-boot-2012.04.01 && arm-linux-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_SYM arch/arm/cpu/arm920t/start.o --start-group api/libapi.o arch/arm/cpu/arm920t/libarm920t.o arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.o arch/arm/lib/libarm.o common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o drivers/power/libpower.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/eth/libusb_eth.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/usb/ulpi/libusb_ulpi.o drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o post/libpost.o board/samsung/smdk2410/libsmdk2410.o --end-group /work/system/u-boot-2012.04.01/arch/arm/lib/eabi_compat.o  -L /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t -lgcc -Map u-boot.map -o u-boot


其中
arm-linux-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_SYM arch/arm/cpu/arm920t/start.o --start-group api/libapi.o arch/arm/cpu/arm920t/libarm920t.o
这句话就是链接,打开start.S,看看里面是什么内容。

2.分析start.S

1.进入管理模式,代码开始执行,

start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0

2.关闭看门狗
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]

3.屏蔽中断
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]

4.设置分频系数
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]

4.板子初始化,这里开始使用C函数,所以要初始化栈
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl  board_init_f


5.进入call_board_init_f函数

这里初始化了一个指针,指向了栈的同一位置,他们并不冲突,栈是向下 增长的,指针是向上的。

gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);


可以看到存了一些数据进入,关于bss段以及一些其他信息的,还有很多gd的配置,没有贴出来,占了挺大一段的

gd->mon_len = _bss_end_ofs;


这里面有这句话,init_fnc_ptr 是一个指针,init_sequence是一个数组,里面有很多函数,这个for就是去循环执行这些函数

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}


里面都是条件编译,我把没宏定义的代码段都去掉了,留下的函数是执行函数,看起来比较方便

init_fnc_t *init_sequence[] = {

#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
timer_init,     /* initialize timer */
#endif
env_init,       /* initialize environment */
init_baudrate,      /* initialze baudrate settings */
serial_init,        /* serial communications setup */
console_init_f,     /* stage 1 init of console */
display_banner,     /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo,      /* display cpu info (and speed) */
#endif
dram_init,      /* configure available RAM banks */
NULL,
};


5.1 board_early_init_f,板子早期初始化函数

设置了分频系数,有点奇怪汇编里面已经设置过了,我要去查一查两个哪个是对的

writel(0xFFFFFF, &clk_power->locktime);

/* configure MPLL */
writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
&clk_power->mpllcon);

/* some delay between MPLL and UPLL */
pll_delay(4000);

/* configure UPLL */
writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
&clk_power->upllcon);

GPIO端口的初始化
/* set up the I/O ports */
writel(0x007FFFFF, &gpio->gpacon);
writel(0x00044555, &gpio->gpbcon);
writel(0x000007FF, &gpio->gpbup);
writel(0xAAAAAAAA, &gpio->gpccon);
writel(0x0000FFFF, &gpio->gpcup);
writel(0xAAAAAAAA, &gpio->gpdcon);
writel(0x0000FFFF, &gpio->gpdup);
writel(0xAAAAAAAA, &gpio->gpecon);
writel(0x0000FFFF, &gpio->gpeup);
writel(0x000055AA, &gpio->gpfcon);
writel(0x000000FF, &gpio->gpfup);
writel(0xFF95FFBA, &gpio->gpgcon);
writel(0x0000FFFF, &gpio->gpgup);
writel(0x002AFAAA, &gpio->gphcon);
writel(0x000007FF, &gpio->gphup);


5.2 在int timer_init(void)里面,有一个get_PCLK()函数被调用,再往里走get_HCLK(),再往里走

ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
#ifdef CONFIG_S3C2440
switch (readl(&clk_power->clkdivn) & 0x6) {
default:
case 0:
return get_FCLK();
case 2:
return get_FCLK() / 2;
case 4:
return (readl(&clk_power->camdivn) & (1 << 9)) ?
get_FCLK() / 8 : get_FCLK() / 4;
case 6:
return (readl(&clk_power->camdivn) & (1 << 8)) ?
get_FCLK() / 6 : get_FCLK() / 3;
}


可以看出里面是有关于2440的宏定义的,当前并没有被定义,所以之后要把这段代码宏定义了,才能执行。

到这里已经有点懵逼了,uboot的代码绕圈程度有点大了。要改的地方感觉挺多的,移植的难度应该会很大。

6.在board_init_f函数的最后面relocate_code(addr_sp, id, addr);重定位代码。

在反汇编文件中一开始的代码位置就是0,让人感觉不需要重定位了。

u-boot:     file format elf32-littlearm

Disassembly of section .text:

00000000 <__image_copy_start>:
0:   ea000013    b   54 <start_code>
4:   e59ff014    ldr pc, [pc, #20]   ; 20 <_undefined_instruction>
8:   e59ff014    ldr pc, [pc, #20]   ; 24 <_software_interrupt>
c:   e59ff014    ldr pc, [pc, #20]   ; 28 <_prefetch_abort>
10:   e59ff014    ldr pc, [pc, #20]   ; 2c <_data_abort>
14:   e59ff014    ldr pc, [pc, #20]   ; 30 <_not_used>
18:   e59ff014    ldr pc, [pc, #20]   ; 34 <_irq>
1c:   e59ff014    ldr pc, [pc, #20]   ; 38 <_fiq>

00000020 <_undefined_instruction>:
20:   000001e0    .word   0x000001e0


实际上是链接的时候可以看到 arm-linux-ld -pie -T u-boot.lds -Bstatic -Ttext ,输入命令arm-linux-ld –help | grep pie,搜索pie命令,回复-pie, –pic-executable Create a position independent executable,也就是说链接的时候加上pie可以生成位置无关的可执行程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  u-boot 移植