aka
Posts: 22
Joined: Tue Apr 28, 2015 9:11 am
Contact: Website

Pi2 network boot

Sun May 03, 2015 2:09 pm

Pi2 can boot by network with u-boot. Real network boot with DHCP and TFTP, like x86 does. SD card is still necessary because there is no BIOS ROM chip in Pi.

U-boot should be patched to use Device Tree. I used oficial u-boot repository and patch from this topic: viewtopic.php?f=29&t=108217
Few lines were added to run kernel directly instead of u-boot script.

Code: Select all

diff --git a/include/configs/rpi-common.h b/include/configs/rpi-common.h
index 3121ac9..ee79846 100644
--- a/include/configs/rpi-common.h
+++ b/include/configs/rpi-common.h
@@ -163,16 +163,15 @@
  *   for the FDT/DTB to be up to 1M, which is hopefully plenty.
  */
 #define ENV_MEM_LAYOUT_SETTINGS \
-       "scriptaddr=0x00000000\0" \
+       "fdt_addr_r=0x00000100\0" \
        "pxefile_addr_r=0x00100000\0" \
        "kernel_addr_r=0x01000000\0" \
-       "fdt_addr_r=0x02000000\0" \
+       "scriptaddr=0x02000000\0" \
        "ramdisk_addr_r=0x02100000\0" \

 #define BOOT_TARGET_DEVICES(func) \
        func(MMC, mmc, 0) \
        func(USB, usb, 0) \
-       func(PXE, pxe, na) \
        func(DHCP, dhcp, na)
 #include <config_distro_bootcmd.h>

@@ -181,6 +180,15 @@
        ENV_MEM_LAYOUT_SETTINGS \
        BOOTENV

-#define CONFIG_BOOTDELAY 2
+#undef  CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY -2
+
+#undef  BOOTENV_DEV_DHCP
+#define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \
+       "bootcmd_dhcp=" \
+               BOOTENV_RUN_USB_INIT \
+               "if dhcp ${kernel_addr_r}; then " \
+                       "bootz ${kernel_addr_r} - ${fdt_addr_r}; " \
+               "fi\0"

 #endif
Script to compile u-boot after patching:

Code: Select all

#!/bin/sh
make CROSS_COMPILE=arm-linux-gnueabihf- distclean
make CROSS_COMPILE=arm-linux-gnueabihf- rpi_2_config
make CROSS_COMPILE=arm-linux-gnueabihf- u-boot.bin
./mkknlimg --dtok u-boot.bin kernel7.img
mkknlimg is taken from git://github.com/raspberrypi/firmware

Here are all files for SD (updated at 08 Sep 2015): http://pxe.ru/files/arm/pi2/2015-09-08- ... etboot.zip Less then 3Mb, no linux kernel.

I made minimal initrd that runs command prompt, nothing more: http://pxe.ru/files/arm/pi2/2015-05-03- ... rd.tar.bz2

It is packed for kernel:

Code: Select all

cd initrd
find * | cpio -oH newc --owner=root:root > ../initrd.cpio
And passed to kernel with:

Code: Select all

CONFIG_INITRAMFS_SOURCE="initrd.cpio"
Here is compiled kernel with initrd: http://pxe.ru/files/arm/pi2/2015-05-03- ... ge.tar.bz2

Put zImage to TFTP server root directory, add two lines to dhcpd.conf, replace 10.1.1.28 with TFTP server IP:

Code: Select all

next-server 10.1.1.28;
filename "zImage";
And it boots by network!


U-boot output to serial console:

Code: Select all

U-Boot 2015.04-00631-gace97d2-dirty (May 03 2015 - 00:25:21)

DRAM:  944 MiB
WARNING: Caches not enabled
RPI 2 Model B
MMC:   bcm2835_sdhci: 0
reading uboot.env

** Unable to read "uboot.env" from mmc0:1 **
Using default environment

In:    serial
Out:   lcd
Err:   lcd
Net:   Net Initialization Skipped
No ethernet found.

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...
USB0:   Core Release: 2.80a
scanning bus 0 for devices... unable to get device descriptor (error=-5)
3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
       scanning usb for ethernet devices... 1 Ethernet Device(s) found

USB device 0: unknown device
Waiting for Ethernet connection... done.
BOOTP broadcast 1
DHCP client bound to address 10.1.1.98 (38 ms)
Using sms0 device
TFTP from server 10.1.1.28; our IP address is 10.1.1.98
Filename 'zImage'.
Load address: 0x1000000
Loading: #################################################################
         #################################################################
         ##########################
         1004.9 KiB/s
done
Bytes transferred = 2275496 (22b8a8 hex)
Kernel image @ 0x1000000 [ 0x000000 - 0x22b8a8 ]
## Flattened Device Tree blob at 00000100
   Booting using the fdt blob at 0x000100
   Loading Device Tree to 3ab43000, end 3ab49eff ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0xf00
[    0.000000] Linux version 3.18.12+ (aka@c8) (gcc version 4.9.2 (Ubuntu/Linaro 4.9.2-10ubuntu10) ) #1 SMP PREEMPT Sun May 3 02:30:19 SAMT 2015
...more kernel lines skipped.

tesla123
Posts: 4
Joined: Thu Oct 22, 2015 10:50 am

Re: Pi2 network boot

Thu Oct 22, 2015 10:53 am

Hi aka.
Great work.
I'll try to compile and patch. Uboot work with serial console.
But your compile version work perfectly on HDMI and with a "base version" of the git and patch not.

Have you done something more to work?

aka
Posts: 22
Joined: Tue Apr 28, 2015 9:11 am
Contact: Website

Re: Pi2 network boot

Thu Oct 22, 2015 12:06 pm

Here's the full patch, that I use now. One line in bcm2835.c fixes HDMI output.

Code: Select all

diff --git a/common/board_r.c b/common/board_r.c
index f8c1baa..a1f1c87 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -580,7 +580,6 @@ static int initr_bbmii(void)
 #ifdef CONFIG_CMD_NET
 static int initr_net(void)
 {
-	puts("Net:   ");
 	eth_initialize();
 #if defined(CONFIG_RESET_PHY_R)
 	debug("Reset Ethernet PHY\n");
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 6bdbbc5..8cbfa9b 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -602,6 +602,7 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	if (strncmp(argv[1], "start", 5) == 0) {
 		if (usb_started)
 			return 0; /* Already started */
+		printf("WTware/Pi2 network boot.\n\n");
 		printf("starting USB...\n");
 		do_usb_start();
 		return 0;
diff --git a/common/usb.c b/common/usb.c
index 700bfc3..91b6c95 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -942,8 +942,6 @@ static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len);
 	if (err < expect_len) {
 		if (err < 0) {
-			printf("unable to get device descriptor (error=%d)\n",
-				err);
 			return err;
 		} else {
 			printf("USB device descriptor short read (expected %i, got %i)\n",
diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index dc8fa88..77aa9a1 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -226,7 +226,7 @@ static int smsc95xx_mdio_read(struct usb_device *udev, int phy_id, int idx)
 	}
 
 	/* set the address, index & direction (read from PHY) */
-	addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+	addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_;
 	smsc95xx_write_reg(udev, MII_ADDR, addr);
 
 	if (smsc95xx_phy_wait_not_busy(udev)) {
@@ -254,7 +254,7 @@ static void smsc95xx_mdio_write(struct usb_device *udev, int phy_id, int idx,
 	smsc95xx_write_reg(udev, MII_DATA, val);
 
 	/* set the address, index & direction (write to PHY) */
-	addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+	addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_;
 	smsc95xx_write_reg(udev, MII_ADDR, addr);
 
 	if (smsc95xx_phy_wait_not_busy(udev))
@@ -345,7 +345,19 @@ static int mii_nway_restart(struct usb_device *udev, struct ueth_data *dev)
 static int smsc95xx_phy_initialize(struct usb_device *udev,
 				   struct ueth_data *dev)
 {
+	int bmcr, timeout = 0;
 	smsc95xx_mdio_write(udev, dev->phy_id, MII_BMCR, BMCR_RESET);
+	do {
+		udelay(10 * 1000);
+		bmcr = smsc95xx_mdio_read(udev, dev->phy_id, MII_BMCR);
+		timeout++;
+	} while ((bmcr & BMCR_RESET) && (timeout < 100));
+
+	if (timeout >= 100) {
+		debug("timeout on PHY Reset\n");
+		return -ETIMEDOUT;
+	}
+
 	smsc95xx_mdio_write(udev, dev->phy_id, MII_ADVERTISE,
 			    ADVERTISE_ALL | ADVERTISE_CSMA |
 			    ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
@@ -683,6 +695,7 @@ static int smsc95xx_init_common(struct usb_device *udev, struct ueth_data *dev,
 		printf("unable to connect.\n");
 		return -EIO;
 	}
+	mdelay(100);
 	return 0;
 }
 
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 7867fe3..1527853 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -104,6 +104,7 @@ void lcd_ctrl_init(void *lcdbase)
 	panel_info.vl_bpix = LCD_COLOR16;
 
 	gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+	gd->fb_base &= ~0xc0000000;
 }
 
 void lcd_enable(void)
diff --git a/include/configs/rpi-common.h b/include/configs/rpi-common.h
index 06836cd..981b616 100644
--- a/include/configs/rpi-common.h
+++ b/include/configs/rpi-common.h
@@ -71,11 +71,6 @@
 #define CONFIG_SYS_WHITE_ON_BLACK
 
 /* SD/MMC configuration */
-#define CONFIG_GENERIC_MMC
-#define CONFIG_MMC
-#define CONFIG_SDHCI
-#define CONFIG_MMC_SDHCI_IO_ACCESSORS
-#define CONFIG_BCM2835_SDHCI
 
 #define CONFIG_CMD_USB
 #ifdef CONFIG_CMD_USB
@@ -85,7 +80,6 @@
 #else
 #define CONFIG_USB_DWC2_REG_ADDR 0x20980000
 #endif
-#define CONFIG_USB_STORAGE
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_SMSC95XX
 #define CONFIG_MISC_INIT_R
@@ -103,7 +97,7 @@
 
 /* Environment */
 #define CONFIG_ENV_SIZE			SZ_16K
-#define CONFIG_ENV_IS_IN_FAT
+#define CONFIG_ENV_IS_NOWHERE
 #define FAT_ENV_INTERFACE		"mmc"
 #define FAT_ENV_DEVICE_AND_PART		"0:1"
 #define FAT_ENV_FILE			"uboot.env"
@@ -119,7 +113,6 @@
 
 /* Commands */
 #define CONFIG_CMD_GPIO
-#define CONFIG_CMD_MMC
 #define CONFIG_PARTITION_UUIDS
 #define CONFIG_CMD_PART
 
@@ -170,9 +163,6 @@
 	"ramdisk_addr_r=0x02100000\0" \
 
 #define BOOT_TARGET_DEVICES(func) \
-	func(MMC, mmc, 0) \
-	func(USB, usb, 0) \
-	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 #include <config_distro_bootcmd.h>
 
@@ -181,6 +171,19 @@
 	ENV_MEM_LAYOUT_SETTINGS \
 	BOOTENV
 
-#define CONFIG_BOOTDELAY 2
+#undef  CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY -2
+
+#undef  BOOTENV_DEV_DHCP
+#define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \
+	"bootcmd_dhcp=" \
+		"usb start; " \
+		"until dhcp ${kernel_addr_r}; do " \
+			"usb reset; " \
+		"done; " \
+		"bootz ${kernel_addr_r} - ${fdt_addr_r}\0"
+
+#undef  CONFIG_BOOTP_VCI_STRING
+#define CONFIG_BOOTP_VCI_STRING         "U-boot.armv7.pi2"
 
 #endif
diff --git a/net/bootp.c b/net/bootp.c
index b2f8ad4..df6635d 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -38,7 +38,7 @@
 #else
 # define TIMEOUT_COUNT	(CONFIG_NET_RETRY_COUNT)
 #endif
-#define TIMEOUT_MS	((3 + (TIMEOUT_COUNT * 5)) * 1000)
+#define TIMEOUT_MS	0
 
 #define PORT_BOOTPS	67		/* BOOTP server UDP port */
 #define PORT_BOOTPC	68		/* BOOTP client UDP port */
@@ -130,6 +130,8 @@ static int check_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
 		retval = -5;
 	else if (!bootp_match_id(net_read_u32(&bp->bp_id)))
 		retval = -6;
+	else if (bp->bp_file [0] == 0)
+		retval = -7;
 
 	debug("Filtering pkt = %d\n", retval);
 
@@ -547,6 +549,10 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
 	*e++  = 42;
 	*cnt += 1;
 #endif
+	*e++  = 66;
+	*cnt += 1;
+	*e++  = 67;
+	*cnt += 1;
 	/* no options, so back up to avoid sending an empty request list */
 	if (*cnt == 0)
 		e -= 2;
@@ -807,6 +813,7 @@ static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
 			memcpy(&net_root_path, popt + 2, size);
 			net_root_path[size] = 0;
 			break;
+		case 26:	/* Ignore MTU */
 		case 28:	/* Ignore Broadcast Address Option */
 			break;
 #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
diff --git a/net/eth.c b/net/eth.c
index 2e24b55..de22d79 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -108,7 +108,6 @@ static void eth_common_init(void)
 			printf("CPU Net Initialization Failed\n");
 	} else {
 #ifndef CONFIG_DM_ETH
-		printf("Net Initialization Skipped\n");
 #endif
 	}
 }
@@ -812,7 +811,6 @@ int eth_initialize(void)
 	eth_common_init();
 
 	if (!eth_devices) {
-		puts("No ethernet found.\n");
 		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
 	} else {
 		struct eth_device *dev = eth_devices;

tesla123
Posts: 4
Joined: Thu Oct 22, 2015 10:50 am

Re: Pi2 network boot

Thu Oct 22, 2015 6:48 pm

big thanks i'll will try :)

tesla123
Posts: 4
Joined: Thu Oct 22, 2015 10:50 am

Re: Pi2 network boot

Thu Oct 22, 2015 7:04 pm

Code: Select all

--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -104,6 +104,7 @@ void lcd_ctrl_init(void *lcdbase)
    panel_info.vl_bpix = LCD_COLOR16;
 
    gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+   gd->fb_base &= ~0xc0000000;
 }      
confirm that work succesfull
I'll test on the last branch u-boot and it work too.
The memory layout have been changed but this bug stil exist :)
I think it will be great to send this bug correct to the mailing list of u-boot
Thanks for your work

tesla123
Posts: 4
Joined: Thu Oct 22, 2015 10:50 am

Re: Pi2 network boot

Thu Oct 29, 2015 12:52 pm

Hi a little (headache) contributed from me:
If you want use the Splash screen of bitmap display in bootmap , there is a bug in the video driver.
The panel_info.cmap is not allocated and have a NULL value. So the cmap is fill at 0x0 and lot's of essential data like device tree too (at 0x100) is overwritten.

Code: Select all

index 7867fe3..6f450b2 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -102,14 +102,16 @@ void lcd_ctrl_init(void *lcdbase)
        panel_info.vl_col = w;
        panel_info.vl_row = h;
        panel_info.vl_bpix = LCD_COLOR16;
-
-       gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+    panel_info.cmap=malloc(256 * NBITS(panel_info.vl_bpix) / 8);
+    gd->fb_base = msg_setup->allocate_buffer.body.resp.fb_address;
+    gd->fb_base &= ~0xc0000000;
 }

 void lcd_enable(void)
 {
 }

+
 int lcd_get_size(int *line_length)
 {
        *line_length = bcm2835_pitch;  

Return to “Advanced users”

Who is online

Users browsing this forum: il_diavolo and 21 guests