The process of writing Uboot Linux kernel file system to Nandflash with Uboot and the start and difference of BOOTM go command

Source: Internet
Author: User
Tags unique id

Original: http://blog.sina.com.cn/s/blog_6b94d5680100nd48.html

Article structure
The structure order has changed
-1: Burn Write Uboot
0:bootargs setting of the bootcmd command parameter
1: The process of making YAFFS2
2: The process of burning and writing YAFFS2
3: The process of making uimage
4: The process of burning and writing Uiamge
The difference between 5:uimage zimage Vmlinux
6:UBOOT parameter structure passed to the kernel tag
7:BOOTM Go boot process and the difference
8: Load address entry address, etc.

Write Uboot to nandflash/////////////by Uboot Burn
//////////////
NAND Erase 0 50000
//////////////
Tftpboot 30008000 U-boot.bin
/////
Loading:t ##################
Done
Bytes transferred = 257164 (3ec8c hex)
[[Email protected]]# NAND write 0x30008000 0 3f000
//////////////
NAND Write 0x30008000 0 3f000 (3ec8c nearest to 2K integer times)



Write kernel to nandflash/////////////by uboot
Check your own board's Nandflash partition table first
Analysis by example: The following burn-write kernel error
[Email protected]]# tftpboot 30008000 uimage
dm9000 I/o: 0x20000300, Id:0x90000a46
Dm9000:running in + bit mode
Mac:08:08:11:18:12:27
Operating at 100M full duplex mode
Using dm9000 Device
TFTP from server 192.168.0.100; Our IP address is 192.168.0.10
Filename ' Uimage '.
Load address:0x30008000
Loading:t #################################################################
#################################################################
##########################
Done
Bytes transferred = 2287128 (22e618 hex)
[Email protected]]# NAND erase 0x60000 0x500000

NAND erase:device 0 Offset 0x60000, size 0x500000
Erasing at 0x54000002800000 – 0% complete.
Ok
[[Email protected]]# NAND write 0x30008000 0x60000 22e618
NAND write:device 0 Offset 0x60000, size 0x22e618
Attempt to write non page aligned data
2287128 bytes Written:error
The following burn-write is correct:
NAND erase:device 0 Offset 0x80000, size 0x500000
Erasing at 0x54000002800000 – 0% complete.
Ok
[[Email protected]440]# NAND write 0x30008000 0x80000 22e800
NAND write:device 0 Offset 0x80000, size 22e800
Changed to two places:
1:0x60000->0x80000
2:0x22e618->22e800
The reason for the modification is: 1: From the 0x60000 sassafras will be removed from the Bootargs Bootcmd also to Sassafras except so choose from 0x80000 start Sassafras
2:0x22e618 Although the actual size of the kernel downloaded through tftpboot, this is the parameter after the write instruction that indicates the length of the Sassafras write length required to be erased is an integer multiple of 2k (2048) (that is, the entire page of the erase) and 0x22e618 is not an integer multiple of 2K, Error attempt to write non page aligned data 2287128 bytes Written:error, so take a nearest number to choose 22e800 OK music
Set the self-starting parameter bootcmd///////////////////
I wrote it this way at first:
SETENV bootcmd NAND read 30008000 80000 22e800; Bootm 30008000
Following the determination, the BOOTM was executed directly, and the order was changed:
SETENV bootcmd NAND read 30008000 80000 22e800 \; Bootm 30008000 is OK.
Download the YAFFS2 image to Nandflash/////////////////////////
Production YAFFS2 and tools please refer to Tekkaman Ninja file uboot Burn write YAFFS2 file system
method is similar to kernel burn-write
First look at your own board Nandflash partition table (such as 128M of the board 128M->8000000 Sassafras write address is starting from the 0x580000 so two subtract equals 7a80000 and my is 256M of the front of the kernel is from the 0x80000 to start the Sassafras except 0x5 00000 length So here the file system starts from 0x580000 to the end of the Nandflash)
128M
First check: Nand erase 0x580000 7a80000
Re-write: Nand write.yaffs 30008000 0x580000 dbb040 (file system size, and here the file system is not the same as the kernel burning length is not an integer multiple of 2K I'm not sure if the answer I found on the web was right, I didn't check it out:mkyaffs2imageThe resulting file system has taken alignment measures on 2K data alignment the user does not have to consider the problem of data alignment, while tools such as mkimage do not use alignment measures so be aware of it)
256M:
First check: Nand erase 0x580000 FA80000
Re-write: Nand write.yaffs 30008000 0x580000 dbb040
Set the Bootargs parameter////////////////////////////////////
1: If using the YAFFS2 file system
setenv bootargs noinitrd root=/dev/mtdblock3 rootfstype=yaffs2 rw console=ttySAC0,115200 init=/linuxrc mem=64M
2: If using NFS file system
setenv bootargs noinitrdRoot=/dev/nfsrwnfsroot= 192.168.0.100:/home/lq/rootfs ip=192.168.0.10 console=ttysac0 mem=64m
BOOTATGS parameter Parsing/////////////////////////
Root
Used to specify the location of the rootfs, common cases are:
Root=/dev/ram RW
Root=/dev/ram0 RW
Please note that the above two settings are general, I have done the test even root=/dev/ram1 RW and root=/dev/ram2 RW is also possible, online some people say in some cases is not universal, that must be set to RAM or RAM0, but not yet encountered, Further confirmation is required, and you can try each time you encounter a problem.
ROOT=/DEV/MTDX RW
Root=/dev/mtdblockx RW
root=/dev/mtdblock/x RW
root=31:0x
The above are common in some cases, of course, it depends on whether your current system is supported, but MTD is a character device, and Mtdblock is a block device, and sometimes you try to get to the bottom of the current system to support the case, but Root=/dev/mtdblockx RW is more versatile. In addition, if you specify the device name directly, it is also possible to use the device number for this device.
Root=/dev/nfs
Used when the file system is an NFS-based file system. Of course, after specifying ROOT=/DEV/NFS, you also need to specify Nfsroot=serverip:nfs_dir, which is the directory that indicates the file system exists for that host.
B. Rootfstype
This option needs to be used in conjunction with root, generally if the root filesystem is ext2, there is no such option is irrelevant, but if it is JFFS2,SQUASHFS and other file systems, you need to rootfstype indicate the type of file system, otherwise you will not be able to mount the root partition.
C. Console
Console=tty uses virtual serial terminal equipment.
Console=ttys[,options] using a specific serial port, options can be the form of BBBBPNX, where BBBB refers to the serial port baud rate, p is the parity bit (never seen used), n refers to bits.
Console=ttysac[,options] with the top.
Look at your current environment, sometimes with ttys, sometimes with Ttysac, online Some people say, this is the kernel version of the 2.4 with TTYSAC, but the fact is the official document is also used TTYs, so should be not associated with the kernel version. You can view Documentation/serial-console.txt to find the relevant description.
D. Mem
MEM=XXM Specifies the size of the memory, not required
E. ramdisk_size
Ramdisk=xxxxx Not recommended
Ramdisk_size=xxxxx recommended
Both of the above can tell the RAMDisk driver, create the size of the RAMDisk, by default is 4m (s390 default 8M), you can view documentation/ramdisk.txt find the relevant description, but ramdisk= XXXXX in the new version of the kernel has not been mentioned, is not recommended to use.
F. Initrd, NOINITRD
When you do not use the RAMDisk boot system, you need to use the NOINITRD this parameter, but if used, you need to specify Initrd=r_addr,size, R_ADDR represents the INITRD in memory location, size represents INITRD.
G. Init
INIT specifies that after the kernel is set up, the first script to run into the system, generally INIT=/LINUXRC, or init=/etc/preinit,preinit, is typically to create console,null device nodes, run the INIT program, Mount some file systems, and so on. Please note that many beginners think INIT=/LINUXRC is a fixed notation, in fact,/LINUXRC refers to the LINUXRC script under the directory, is generally a connection.
H. mtdparts
mtdparts=fc000000.nor_flash:1920k (Linux), 128k (FDT), 20M (RAMDisk), 4M (JFFS2), 38272k (user), 256k (env), 384k (Uboot)
In order for this parameter to work, the MTD driver in the kernel must be supported, that is, the kernel configuration needs to be selected on Device Drivers---> Memory technology Device (MTD) Support---> Command line P Artition Table Parsing
The mtdparts format is as follows:
mtdparts=[;
:= :[,]
: = [@offset][][ro]
: = Unique ID used in mapping driver/device
: = Standard Linux memsize OR "-" to denote all remaining space
: = (NAME)
So you need to set it in the following format when you use it:
mtdparts=mtd-id:@ (), @ ()
Here are a few important points to note:
A. Mtd-id must be consistent with the flash Mtd-id of your current platform, or the entire mtdparts will fail
B. Size can be set to the actual size (xxm,xxk,xx), or '-' which indicates all the remaining space.
Example:
Assuming that the mtd-id of Flash is sa1100, then you can use the following method to set:
mtdparts=sa1100:-→ only one partition
mtdparts=sa1100:256k (Armboot) ro,-(root) → has two partitions
You can see the comments in drivers/mtd/cmdlinepart.c to find the relevant description.
I. IP
Specify the IP address of the network card after the system starts, if you use an NFS-based file system, you must have this parameter, and in other cases you will see your own preferences. There are two ways of setting up IP:
ip = IP Addr
Ip=ip addr:server IP Addr:gateway:netmask::which netcard:off
These two methods can be used, but obviously the second is much more detailed, note that the second type of which netcard refers to the network card on the Development Board, not the network card on the host.
After talking about several common Bootargs, let's discuss some of the combinations that I usually use frequently:
1). Assuming that the file system is ramdisk and directly in memory, the Bootargs settings should be as follows:
Setenv Bootargs ' initrd=0x32000000,0xa00000 root=/dev/ram0 console=ttysac0 mem=64m init=/linuxrc '
2). Assuming the file system is RAMDisk, and in Flash, the Bootargs settings should be as follows:
Setenv Bootargs ' mem=32m console=ttys0,115200 root=/dev/ram rw init=/linuxrc '
Note In this case you should specify RAMDisk address in Flash in the BOOTM command, such as Bootm kernel_addr ramdisk_addr (FDT_ADDR)
3). Assuming that the file system is of type JFFS2, and in Flash, the Bootargs settings should be as follows
Setenv Bootargs ' mem=32m console=ttys0,115200 noinitrd root=/dev/mtdblock2 rw rootfstype=jffs2 init=/linuxrc '
4). Assuming that the file system is NFS based, the Bootargs settings should be as follows
Setenv Bootargs ' noinitrd mem=64m console=ttysac0 root=/dev/nfs nfsroot=192.168.0.3:/nfs ip= 192.168.0.5:192.168.0.3:192.168.0.3:255.255.255.0::eth0:off '
Or
Setenv Bootargs ' noinitrd mem=64m console=ttysac0 root=/dev/nfs nfsroot=192.168.0.3:/nfs ip=192.168.0.5 '
BOOTM Go boot process and the difference/////////////////////
The BOOTM command is in the DO_BOOTM function in/COMMON/CMD_BOOTM.C
//////////////////
By mkimage This tool you can add a header to Zimage:
typedef struct IMAGE_HEADER
{
uint32_t ih_magic;
uint32_t IH_HCRC;
uint32_t Ih_time;
uint32_t ih_size;
uint32_t ih_load;
uint32_t Ih_ep;
uint32_t IH_DCRC;
uint8_t Ih_os;
uint8_t Ih_arch;
uint8_t Ih_type;
uint8_t Ih_comp;
uint8_t Ih_name[ih_nmlen];
} image_header_t;
The size of the head is 0x40 64 bytes, 64byte of information, for the purpose of building the tag, pass parameters to the kernel via tag
Mkimage parameter Description:
For ARM Linux kernel image usage:
-A arm--------architecture is arm
-O Linux--------operating system is Linux
-T kernel--------type is kernel
-C none/bzip/gzip--------compression type
-a 30008000----image's load address (hex), typically 0xx00008000
-e 300080XX----Kernel entry address (hex), xx 0x40 or 0x00
-N linux-xxx---The name of the image, any
-D namexxx----The image file name of the headless message, your source kernel file
UIMAGEXXX----The image file name after the header message is added, arbitrary fetch

Mkimage-n ' Liquan_kernel '-A arm-o linux-t kernel-c none-a 0x30008000-e 0x30008040-d zimage A_zImage
Mkimage-n ' Liquan_kernel '-A arm-o linux-t kernel-c none-a 0x30008000-e 0x30008000-d zimage B_zImage
The above uimage kernel image with the Mkimage command created two headers with the BOOTM command
Have done an experiment like this:
1:
Tftpboot 30008000 A_zimage
Bootm 30008000
2:
Tftpboot 31000000 B_zimage
Bootm 31000000
Can all start successfully
Corresponding to the second experiment if you change the production b_zimage to-a 0x30008000-e 0x30008040 that is, the kernel's load address is different from the kernel's entry address so tftpboot 31000000 B_zimage;bootm 31000000 That's not going to start.
tftpboot xxxx kernel image
Bootm xxxx
For non-gzip compressed kernel images (non-gzip compression see below here-C none uncompressed)
The BOOTM command first determines whether the XXXX in BOOTM xxxx is the same as the load address specified by-A in mkimage.
1: Same
If it's the same, then let it be the same, but the-e specifies the entry address will be pushed back 64byte, to skip the 64byte head, and then start
2: Different
If different words will be extracted from this address at the beginning of the 64byte head, analysis, and then the removal of the head of the kernel copy to a specified load address to run in this case is required a 0x30008000-e 0x30008000 is required The kernel entry address is the same as the load address. Because there's no head.
For gzip-compressed kernels: (Unzip the kernel to the address specified by-A This is the kernel entry address)
Because U-boot to unzip it, so tftpboot is not equal to the address specified by-A, and must have a certain interval, otherwise the kernel extracted to-a will overwrite the currently running program. Require-a equals the address specified by-E at this time

The difference between various compressed files//////////////////////////////////////////
The compilation of the kernel will produce zimage zimage is vmlinux gzip compressed files, they are not only a compressed file, and at the beginning of this file is embedded with the GZIP decompression code.
By Mkimage-c None/bzip2/gzip can determine whether the production of uimage is compressed (so the above uimage is gzip compressed)
If Mkimage-c Bzip2/gzip to zimage further compression then download inside SDRAM inside after first is BOOTM implementation for Mkimage-c Bzip2/gzip The first step for Uimage decompression (this can be called U-boot decompression) and then zimage self-extracting (kernel self-extracting)
////////////////
Zimage in front has been compressed once (this time the decompression is self-extracting is not uboot compression, so for uboot this is not a compressed file), so when using mkimage if the-c specifies to compress then u-boot to the kernel add the head, you can the original zimage/ Image adds u-boot compression to make the resulting uimage smaller. At this point,-c gzip If the zimage/image is not compressed with the gzip command, then-C none. Combined with the above analysis, the influence factors of mkimage are:
-e: Whether the kernel's ingress address is the same as-a
TFTPADDR: The kernel is loaded into RAM to run the address, decide whether to move or unzip the kernel, TFTPADDR and-a specified load address is the same, if the tftpaddr and a is different then remove the head after moving to-a operation, if-C compression over the Tftpboot address cannot be the same as-A to prevent overwriting
C: Whether the kernel has been gzip compressed, decided to transport or decompression compression on the decompression to-a address where there is no compression if the tftpaddr and a are different then remove the head and move to-a operation
/////////////////
Vmlinux:
The most primitive kernel file compiled, uncompressed.
Zimage:
Vmlinux after gzip compressed files, they are not only a compressed file, but also in the beginning of these two files are embedded with the GZIP decompression code. So you can't unpack vmlinuz with Gunzip or GZIP–DC.
Bzimage:
BZ means "bigzimage", not compressed with bzip2. The difference is that zimage unzip the kernel to low-end memory (the first 640K), bzimage the kernel to high-end memory (1M or more). If the kernel is relatively small, then the use of Zimage or bzimage are OK, if the larger should be used bzimage.
Uimageu-boot:
Dedicated image file, which is tagged with a length of 0x40 before Zimage.
Vmlinuz:
A copy of the Bzimage/zimage file or a link to the bzimage/zimage. The kernel file contains a miniature gzip to decompress the kernel and boot it. The difference is that the old Zimage unzip the kernel to low-end memory (the first 640K), bzimage the kernel to high-end memory (1M or more). If the kernel is small, you can use one of the zimage or Bzimage, and the two modes of booting the system run the same. The large kernel uses bzimage and cannot use Zimage.
Bootm Go boot//////////////////////////////////////////////
Through the emulator can be very clear see Bootm has completed 2 parts of the work. Can analyze Bootm source code
1.set Bootargs Pass Parameters
2.set pc, R0, R1
The emulator can clearly see that go has completed 2 parts of the work. Can analyze Bootm source code
The GO command essentially changes the current PC value
Transform the GO command with the emulator
A. Change the general register value to
B. Modifying the value of a 0x08000100 address through the emulator
Then let the program execute, so that through Uboot can also allow Zimage to execute.

The difference between go and BOOTM is that go just rewrites the PC value, and BOOTM in addition to PC transfer R0,R1,R2 and Bootargs
BOOTM Boot Process///////////////////////////////////////////////
BOOTM command Do_bootm function in/COMMON/CMD_BOOTM.C
"" ("" "" "" "" "to get the address of the current kernel, the default address or the first parameter of BOOTM
The default load address or pass to the BOOTM command (priority) needs to be consistent with the actual kernel storage address
if (ARGC < 2) {
addr = load_addr; LOAD_ADDR = cfg_load_addr;
} else {
Addr = Simple_strtoul (argv[1], NULL, 16);
}
printf ("# # booting image at LX ... \ n", addr);

"" "" "" In "" "" Mkimage "
Memmove (&header, (char *) addr, sizeof (image_header_t));

"" "" "," "" "" "Print head information
PRINT_IMAGE_HDR ((image_header_t *) addr);
Instance:
Image name:dd-kernel-2.4.19
Image type:arm Linux Kernel Image (gzip compressed)
Data size:869574 Bytes = 849.2 KB
Load address:20008000
Entry point:20008000

"", "" "" "" "" "" ""
printf ("Verifying Checksum ...       "); printf ("ok\n");

"" ("" "" "" "" "") "to check if the architecture supported by image is the-a option for arm or PPC, etc.

"" "" "" "" "" "" "Check the type of image
Type_multi refers to the kernel and file system together, there is a dividing line behind the kernel
Switch (hdr->ih_type)
Case Ih_type_kernel:
Name = "Kernel Image";
Break
Case IH_TYPE_MULTI:

"" "", "" "" "to determine the compression type of the kernel
If the kernel here compresses the concept of non-zimage and image, it refers to whether the kernel is compressed with gunzip, etc. before being mkimage processed.
Switch (HDR-&GT;IH_COMP) {
Case Ih_comp_none://non-compressed kernel
if (Ntohl (hdr->ih_load) = = addr) {
The current kernel holds the same address as specified by-A, do not move,-e must be a large 0x40
printf ("XIP%s ... ", name);
} else {
The current kernel holds an inconsistent address specified by-A, then the kernel is moved to the-a address, at which point-a and-e will be the same
Memmove (void *) Ntohl (hdr->ih_load), (UCHAR *) data, Len);
。。。。
Case Ih_comp_gzip:
printf ("uncompressing%s ... ", name);
if (gunzip (void *) Ntohl (hdr->ih_load), Unc_len,
Compressing the kernel, extracting the kernel from the head to the address specified by-A, requiring the same as-A and-E
To prevent overwriting during decompression, the kernel holds the address preferably behind-a for the compressed kernel
(UCHAR *) data, (int *) &len)! = 0) {
Do_reset (CMDTP, Flag, argc, argv);
}
Break

"" "(" "" "" "" "" "" "" "in" the "" "in the judging operating system type
Switch (hdr->ih_os) {
Default
Case Ih_os_linux:
Do_bootm_linux (CMDTP, Flag, argc, argv, addr, len_ptr, verify);
The first four are passed to Bootm, addr is the initial storage address of the kernel, no use
Break

#ifdef CONFIG_PPC
Static BOOT_OS_FCN Do_bootm_linux;
#else
extern BOOT_OS_FCN Do_bootm_linux;
The Do_bootm_linux function implementations of PPC and other architectures are not the same.
"" "(" "" "" "" "" "" "" in "the start of the Linux kernel
Do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
int argc, char *argv[],
ULONG addr,
ULONG *len_ptr,
int verify)

"" ("" "" "" "" "In" "" "to get Command line parameters
if ((s = getenv ("Bootargs")) = = = NULL)
s = "";
strcpy (cmdline, s);

"" "(" "" "" "" "" in "the Kernel start address
kernel = (void (*) (bd_t *, ULONG, ULONG, ULONG, ULONG)) hdr->ih_ep;
Note that for a compressed kernel, the kernel is decompressed to the address specified by-A, and the-A and-e addresses must be the same

"" "" "In" Bootm "" in judging whether there are initrd in the command parameters of the
if (argc >= 3) {
Addr = Simple_strtoul (argv[2], NULL, 16);
printf ("# # Loading RAMDisk Image at lx ... \ n", addr);

If INITRD is assigned, otherwise 0

"" "(" "" "" "" "" "" "" "in" the start of the Linux kernel

*KBD = * (GD-&GT;BD); The values assigned above are
(*kernel) (KBD, Initrd _start, Initrd_end, Cmd_start, cmd_end);

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.