在u-boot里面加入Android lk bootloader的一键烧写功能(3)

3 篇文章 1 订阅
3 篇文章 0 订阅

        烧写完成之后我们需要启动,我们看看lk怎么启动的吧。

      

int boot_linux(int argc, const cmd_args *argv)
{
		read_nand((u_char *)0x40007800 , 7, 0x800000);//将boot.img读入到内存的0x40007800地址中
		char *linux_cmd,*ramdisk_size;
		char *p;
		unsigned char *flag = KERNEL_ADDR + header_read(0);//header_read(0)表示kernel大小,header_read(1)表示ramdisk大小
		unsigned char *base = RAMDISK_ADDR;
		
		memset(params, 0, sizeof(struct tag));//设定一些列的参数,与启动内核相关
 

		params->hdr.tag = ATAG_CORE;
		params->hdr.size = tag_size(tag_core);
		params->u.core.flags=0;
		params->u.core.pagesize = 0;
		params->u.core.rootdev = 0;
		params = tag_next(params);

		
		params->hdr.tag = ATAG_CMDLINE;
		linux_cmd = "root=/dev/ram0 rw console=ttyS0,115200 mem=216mb init=/init";
	         /*定位ramdisk的头部,因为我们说过,ramdisk是以1F8B080000开头的*/
		while(1){
			if( *(flag-1) == 0 && *flag == 0x1F && *(flag+1) == 0x8B)
				break;
			flag++;
		}
		printf("\nthe location of flag is :0x%0x",flag);
		memcpy(base,flag,header_read(1));
		for (p = linux_cmd; *p == ' '; p++);
		params->hdr.size = (sizeof(struct tag_header)+strlen(p)+1+4)>>2;
		strcpy(params->u.cmdline.cmdline,p);
		params = tag_next(params);

		setup_initrd_tag(RAMDISK_ADDR,header_read(1));	

		params->hdr.tag = ATAG_NONE;
		params->hdr.size = 0;
		printf("Set environment end !\n");
		void (*entry)(unsigned,unsigned,unsigned*) = KERNEL_ADDR;
 	 	entry (0, MACHINE_ID, TAG_ADDR);	//linux入口
    	return 0;
}
        Android的启动和一般的linux启动不太相同。因为我们之前说过,Android的kernel是存放于boot.img里面的,这样我们想要引导linux内核,就要从boot.img中将kernel解析出来。可能由于内核编译时指定的需要,我们的内核地址、ramdisk、传参的地址都需要固定,否则无法启动(有待验证)。它们的地址指定如下:


#define START_ADDR 0x40007800
#define TAG_ADDR 0x40000100
#define KERNEL_ADDR 0x40008000
#define RAMDISK_ADDR 0x42000000

#define MACHINE_ID 2556  //我们板子的机器码ID


      因此我们在上电之后就需要将boot.img读入到内存的0x40007800地址中,然后将ramdisk拷贝到0x42000000地址中,并且设置linux启动所需要的参数。这样才能最终启动linux。


了解了lk如何启动linux之后,我们可以如法炮制,直接在u-boot里面加入同样的命令进行启动。还有一点需要说明的是我们没有办法直接利用u-boot的bootm指令来启动我们的Android,因为u-boot启动的linux内核需要uImage格式的内核镜像,uImage在zImage的头部加入了64byte的头部信息,而我们boot.img里面的image并不符合uImage。所以启动linux需要我们直接实现。好在lk已经告诉了我们应该如何启动了。如上一篇文章中一样我们在u-boot/common/下添加一个cmd_lkboot.c文件用来实现我们自己的启动。并将其加入编译。


在整个过程进行完之后发现了另外一个问题,那就是我们的lk在内存里面的运行地址为0x42800000 ,而我们的u-boot运行的地址为0x40400000,如果将boot.img读取到0x40007800之后因为boot.img文件的大小为6MB+,所以会将u-boot整个冲掉,导致无法完成。所以我们需要将u-boot搬移到更远端的地址。需要修改的有:

(1)u-boot/include/configs/SEP0611.h中相关的地址#define CONFIG_SYS_TEXT_BASE   #define CONFIG_UBOOT_BASE

(2)u-boot/arch/unicore/cpu/unicore32/u-boot.lds:        . = 0x42800000;

(3)u-boot/arch/unicore/cpu/unicore32/start.S 中的相关地址

(4)u-boot/arch/unicore/cpu/unicore32/SDIO.c nand.c相关的拷贝地址


修改完成!至此,我们就可以在uboot中使用dnw进行烧写然后用nandmtd命令进行解析,并用lkboot指令启动android系统了!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值