OpenWrt Forum Archive

Topic: New Broadcom BCM63xx codebase with GPL'd Ethernet and USB support

The content of this topic has been archived between 8 Feb 2018 and 7 May 2018. Unfortunately there are posts – most likely complete pages – missing.

(ALICE GATE VOIP 2 PLUS WIFI BUSINESS)

Hi,

today we will try the last trunk revision to test the echi module.

I've a question:

the kernel found two switch, one on eth0 with driver adm6996 which doesn't seem to be connected on any port, and one roboswitch (driver bcm53xx) on eth1 wich work perfectly. Naturally eth0 and eth1 have two different mac.

Any idea of what is the eth0 interface? Something related with adsl or voip interfaces?

In the mean time we have made some test with the ROBOSwitch.

Internal Port: 5
Switch Port: 0 1 2 3 (respectively port labeled 1 2 3 4)
The port number 4 appear to be unused.

So for example (as the dsl modem doesn't work and you wish to use an external modem):

config switch eth1
    option vlan0 "0 1 2 5*"
    option vlan1 "3 5"

Will let you use the eth1.1 in the ifname option of your wan section.

Is it possible to have a different /etc/config/network files only on the agpf-s0 image? Or I could just change the included packages with the profiles method.

(Last edited by fw_crocodile on 11 Apr 2009, 14:30)

May be an error in the board_bcm963xx.c?

I should delete or disable one "enet" ?

What are exactly the meaning of has_enet and why enet0 and enet1 have different settings?

See .has_phy .has_internal_phy .force_speed .force_duplex_full.

There is nothing wrong with the current configuration. What is happening is that the switch driver probes for two known types of switches : ADM6996 and Broadcom BCM536x. It first probes for the ADM6996 switch and then for the broadcom switch. Eth0 is the "WAN" port of the device and has an internal phy and one dedicated Ethernet MAC. Eth1 is connected to a switch (external) using MII and also has a dedicated ethernet MAC. You should not have to modify anything.

florian_ wrote:

There is nothing wrong with the current configuration. What is happening is that the switch driver probes for two known types of switches : ADM6996 and Broadcom BCM536x. It first probes for the ADM6996 switch and then for the broadcom switch. Eth0 is the "WAN" port of the device and has an internal phy and one dedicated Ethernet MAC. Eth1 is connected to a switch (external) using MII and also has a dedicated ethernet MAC. You should not have to modify anything.

Perfect, thank's for the answer.

So eth0 is related to the adsl part of the SoC? That's the only wan port available on the alice.

What surprise me (not the only thing :-)) is that the external (eth1) is recognized by the driver as a bcm53xx, and the internal as an AMD6996. As the SoC is a broadcom device i would have expected to opposite.

Humm, I badly explained the goal of eth0, eth0 can also be used a the TV decoder port. There is no support for the ADSL interface yet. I do not know how they connected the two Ethernet MACs on the Alice box but I do not think there is an ADM6996 switch at all, rather it's misdetected.

florian_ wrote:

I do not think there is an ADM6996 switch at all, rather it's misdetected.

That was my first tought, but they have two different mac.

eth1 (bcm53xx) is certainly on the 4 port switch, the vlan capabilities works perfectly.

There are other two VoIP port but I think they are FXS, so i suppose connected to the DSP, but i can be wrong on that, i will try to see if they are not simple ethernet port on eth0.

I have compiled a new image from the last trunk.
I have flashed it into my Pirelli gate voip 2+ wi-fi, but after restart, when it try to run the imge it show me this error:

Trying to boot from FIRST image copy (0x80010000) ...
 latest imageSequence found: ... 0
 - Flash Kernel Address: 0xBE020100
 - Tag->kernelLen: 0x000C4271
 - Flash Kernel Address: 0xBE020100
Linux kernel CRC error.  Corrupted image?
 - Tag Kernel crc : 0x7E784BFE - calculated: 0x7415DA04
web info: Waiting for connection on socket 0.

Is the trunk bugged?

I have re-tried my previus build and it works, so it's a problem of the trunk version

ramponis wrote:

I have compiled a new image from the last trunk.
I have flashed it into my Pirelli gate voip 2+ wi-fi, but after restart, when it try to run the imge it show me this error:

Linux kernel CRC error.  Corrupted image?
 - Tag Kernel crc : 0x7E784BFE - calculated: 0x7415DA04

I have re-tried my previus build and it works, so it's a problem of the trunk version

Yes there is a little problem to resolv with imagetag, because the CFE from various modem keep a different behaviour. I'm waiting to have an alice under my hands to resolv elegantly the problem (i hope before the end of the week) and file the solution to florian.

For the moment just commenting line 194 in the source of imagetag (tools/firmware-utils/src/imagetag.c) resolv the problem.

/* Write the RootFS */
        fseek(binfile, rootfsoff - fwaddr, SEEK_SET);
        while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
                crc = crc32(crc, readbuf, read);
                fwrite(readbuf, sizeof(uint8_t), read, binfile);
        }
/* Write the RootFS */
        fseek(binfile, rootfsoff - fwaddr, SEEK_SET);
        while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
//              crc = crc32(crc, readbuf, read);
                fwrite(readbuf, sizeof(uint8_t), read, binfile);
        }

Thank you fw_crocodile.

Now it works wink

if i can... other question

i have loaded only the usb1 support

i tried ti plug a little usb pen from the serial i see that the router recognize it

usb 1-1: new full speed USB device using bcm63xx_ohci and addres
s 2
usb 1-1: configuration #1 chosen from 1 choice
scsi0 : SCSI emulation for USB Mass Storage devices
scsi 0:0:0:0: Direct-Access              USB BAR          1.13 PQ: 0 ANSI: 0 CCS
sd 0:0:0:0: [sda] 253952 512-byte hardware sectors (130 MB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Assuming drive cache: write through
sd 0:0:0:0: [sda] 253952 512-byte hardware sectors (130 MB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Assuming drive cache: write through
 sda:
sd 0:0:0:0: [sda] Attached SCSI removable disk

But it do not mount it, why?

I have tried to install a lot the packages but the problem remain

kmod-fs-ext2 2.6.27.21-brcm63xx-1  
kmod-fs-ext3 2.6.27.21-brcm63xx-1  
kmod-fs-msdos 2.6.27.21-brcm63xx-1  
kmod-fs-ntfs 2.6.27.21-brcm63xx-1  
kmod-fs-udf 2.6.27.21-brcm63xx-1  
kmod-fs-vfat 2.6.27.21-brcm63xx-1  
kmod-nls-base 2.6.27.21-brcm63xx-1  
kmod-nls-cp1250 2.6.27.21-brcm63xx-1  
kmod-nls-cp1251 2.6.27.21-brcm63xx-1  
kmod-nls-cp437 2.6.27.21-brcm63xx-1  
kmod-nls-cp850 2.6.27.21-brcm63xx-1  
kmod-nls-cp852 2.6.27.21-brcm63xx-1  
kmod-nls-iso8859-1 2.6.27.21-brcm63xx-1  
kmod-nls-iso8859-15 2.6.27.21-brcm63xx-1  
kmod-nls-iso8859-2 2.6.27.21-brcm63xx-1  
kmod-nls-koi8r 2.6.27.21-brcm63xx-1  
kmod-nls-utf8 2.6.27.21-brcm63xx-1  
kmod-ppp 2.6.27.21-brcm63xx-1  
kmod-pppoe 2.6.27.21-brcm63xx-1  
kmod-scsi-core 2.6.27.21-brcm63xx-1  
kmod-switch 2.6.27.21-brcm63xx-1  
kmod-usb-core 2.6.27.21-brcm63xx-1  
kmod-usb-ohci 2.6.27.21-brcm63xx-1  
kmod-usb-storage

If i add kmod-usb2_2.6.27.21-brcm63xx-1

when i plug the usb pen into the port, from the serial i receive continuously...

hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
hub 2-0:1.0: over-current change on port 2
...

(Last edited by ramponis on 6 Apr 2009, 17:06)

Compiled and flashed r15157
Same problem on the usb

Okay I've been working on the imagetag to try to get the stock firmware to flash via web or tftp.  I've looked at the source and the rootfs is used to specify the beginning of the area to be flashed. I was able to get the board to boot a kernel by setting both the kernel and rootfs offset to the kernel offset, but the kernel panics when loading the rootfs because the mtdblock2 is pointing to the wrong offset (kernel offset). 

I don't know how to fix this unless the kernel can be made to use reverse the kernel and rootfs mtd (maybe use a reserved section of the imagetag to specify that that is how the tag is written, so that 'normal' tags don't reverse things?)

... Oh wait, that won't work.  The kernel offset still needs to be the kernel offset or the router can't boot (I tried it)

Any way to have the rootfs then kernel like the stock firmware?

Provided that you tell imagetag to first insert the rootfs then the kernel and you make the bcm963xx-flash driver aware of that I do not see a reason why this should not work. At least since we are that way consistent with what's on the flash it should be working, what do you think about this ?

Seems like the offending part of the MTD driver is located between lines 105 and 120. Both the kernellen and rootfslen are non zero, so both will have their MTD parts created, but not in the right order since we are checking first for the kernel lenght and then the rootfs lenght. Inverting both should do the trick.

cshore, does such a patch work for you ?

Index: tools/firmware-utils/src/imagetag.c
===================================================================
--- tools/firmware-utils/src/imagetag.c (revision 15145)
+++ tools/firmware-utils/src/imagetag.c (working copy)
@@ -155,42 +155,42 @@
                return 1;
        }

-       /* Build the kernel address and length (doesn't need to be aligned, read only) */
-       kerneloff = fwaddr + sizeof(tag);
-       kernellen = getlen(kernelfile);
+       /* Build the rootfs address and length (doesn't need to be aligned, read only) */
+       rootfsoff = fwaddr + sizeof(tag);
+       rootfslen = getlen(rootfsfile);

        /* Build the kernel header */
        khdr.loadaddr   = htonl(loadaddr);
        khdr.entry      = htonl(entry);
-       khdr.lzmalen    = htonl(kernellen);
+       khdr.lzmalen    = htonl(getlen(kernelfile));

        /* Increase the kernel size by the header size */
-       kernellen += sizeof(khdr);
+       rootfslen += sizeof(khdr);

        /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */
-       rootfsoff = kerneloff + kernellen;
-       rootfsoff = (rootfsoff % flash_bs) > 0 ? (((rootfsoff / flash_bs) + 1) * flash_bs) : rootfsoff;
-       rootfslen = getlen(rootfsfile);
-       rootfslen = (rootfslen % flash_bs) > 0 ? (((rootfslen / flash_bs) + 1) * flash_bs) : rootfslen;
+       kerneloff = rootfsoff + rootfslen;
+       kerneloff = (kerneloff % flash_bs) > 0 ? (((kerneloff / flash_bs) + 1) * flash_bs) : kerneloff;
+       kernellen = getlen(kernelfile);
+       kernellen = (kernellen % flash_bs) > 0 ? (((kernellen / flash_bs) + 1) * flash_bs) : kernellen;

-       /* Seek to the start of the kernel */
-       fseek(binfile, kerneloff - fwaddr, SEEK_SET);
+       /* Seek to the start of the rootfs */
+       fseek(binfile, rootfsoff - fwaddr, SEEK_SET);

        /* Write the kernel header */
        crc = crc32(IMAGETAG_CRC_START, (uint8_t*)&khdr, sizeof(khdr));
        fwrite(&khdr, sizeof(khdr), 1, binfile);

-       /* Write the kernel */
-       while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) {
-               read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile);
+       /* Write the rootfs */
+       while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
+               read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
                crc = crc32(crc, readbuf, read);
                fwrite(readbuf, sizeof(uint8_t), read, binfile);
        }

-       /* Write the RootFS */
-       fseek(binfile, rootfsoff - fwaddr, SEEK_SET);
-       while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
-               read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
+       /* Write the kernel */
+       fseek(binfile, kerneloff - fwaddr, SEEK_SET);
+       while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) {
+               read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile);
                //crc = crc32(crc, readbuf, read);
                fwrite(readbuf, sizeof(uint8_t), read, binfile);
        }
Index: target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
===================================================================
--- target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c       (revision 15145)
+++ target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c       (working copy)
@@ -103,13 +103,6 @@
        parts[curpart].size = master->erasesize;
        curpart++;

-       if (kernellen > 0) {
-               parts[curpart].name = "kernel";
-               parts[curpart].offset = kerneladdr;
-               parts[curpart].size = kernellen;
-               curpart++;
-       };
-
        if (rootfslen > 0) {
                parts[curpart].name = "rootfs";
                parts[curpart].offset = rootfsaddr;
@@ -118,6 +111,12 @@
                        parts[curpart].size += sparelen;
                curpart++;
        };
+       if (kernellen > 0) {
+               parts[curpart].name = "kernel";
+               parts[curpart].offset = kerneladdr;
+               parts[curpart].size = kernellen;
+               curpart++;
+       };
        parts[curpart].name = "nvram";
        parts[curpart].offset = master->size - master->erasesize;
        parts[curpart].size = master->erasesize;

IMAGETAG

I'm working on imagetag to give it more adaptabilty (some more options on how to build the image and compute the CRC32)

It's almost done but i have some question as the only device on which i can test it is the Alice Gate VoIP 2 Plus ....

(I can definitely confirm that the Alice consider to CRC32 of the image as the crc32 of the kernel)

1 - Imagetag use a wrong image lenght?

sprintf(tag.imagelen, "%lu", kernellen + rootfslen);

But the real lenght  should be

sprintf(tag.imagelen, "%lu", rootfsoff + rootfslen - kerneloff);

to include the rootfsoff alignement

2 - At present the crc32 is computed directly from the vmlinux and rootfs files (and tag structure). But this time too the crc32 do not consider the alignement of both rootfsoff and rootfslen in the final image.

Everything should remain as is, or these are errors that don't caused problem for the moment but should be corrected?

@florian:
Thanks.  I'll test tonight; I think the flash driver part was what I needed - I need to change imagetag differently because the crc calculation is wrong in the one in svn.  I've figured out how to get it right, the part I was missing was swapping the rootfs and kernelfs mtd because of the fact the stock firmware is stupid and requires that the rootfs offset be the offset of the start of the image (after tag).

@fw_crocodile:
The crc calculation needs to do any padding needed to start on an erase boundary, rootfs, then any padding to even out erase boundaries, then kernel header, then kernel, then any kernel padding for erase boundaries (that last padding may not be necessary).  I should have a patch for that tonight.

Doing that will allow for loading from the stock firmware web/tftp interface (broadcom supplies that code so most broadcom based boards will work with these changes).

I should have a patch tonight.

fw_crocodile wrote:

In the mean time we have made some test with the ROBOSwitch.

Internal Port: 5
Switch Port: 0 1 2 3 (respectively port labeled 1 2 3 4)
The port number 4 appear to be unused.

So for example (as the dsl modem doesn't work and you wish to use an external modem):

config switch
    vlan0 "0 1 2 5*"
    vlan1 "3 5"

Will let you use the eth1.1 in the ifname option of your wan section.

Do you have to run robocfg to setup up the vlans first?  I used something like that code but it didn't do anything to the switch, so I've been using the switch setup script called by the network setup init script in order to do some robocfg settings first so that vlan's are available (otherwise the above, for me, was just calling vconfig, but not configuring the switch, so the vlan's didn't actually work).

(Last edited by cshore on 9 Apr 2009, 22:07)

cshore wrote:

@fw_crocodile:
The crc calculation needs to do any padding needed to start on an erase boundary, rootfs, then any padding to even out erase boundaries, then kernel header, then kernel, then any kernel padding for erase boundaries (that last padding may not be necessary).  I should have a patch for that tonight.

Doing that will allow for loading from the stock firmware web/tftp interface (broadcom supplies that code so most broadcom based boards will work with these changes).

I should have a patch tonight.

I've done some work on imagetag in the past day, take a look at ticket 4909. It's my first try in C so there are probably some possible improvement.

cshore wrote:

Do you have to run robocfg to setup up the vlans first?  I used something like that code but it didn't do anything to the switch, so I've been using the switch setup script called by the network setup init script in order to do some robocfg settings first so that vlan's are available (otherwise the above, for me, was just calling vconfig, but not configuring the switch, so the vlan's didn't actually work).

I made a stupid error in the above post.

If you use the same syntax as I posted above (i just correct it know to avoid furter problem) it'will certainly not work as I forgot the term "option".

So a correct config section for the switch is:

config switch eth1
    option vlan0 "0 1 2 5*"
    option vlan1 "3 5"

without the "option" option_cb () (switch.sh) is never called, and consequentially neither setup_switch_vlan () which does the echo in /proc/switch/ethX/vlan/X/ports.

You need to specify the ethernet port too.

So finally robocfg is not needed.

Sorry for the mistake.

(Last edited by fw_crocodile on 11 Apr 2009, 14:31)

After getting kamikaze 8.09 source, configuring it for BCM 6358 and building it i've got following in bin folder:

openwrt-96345GW2-jffs2-128k-cfe.bin
openwrt-96345GW2-jffs2-64k-cfe.bin
openwrt-96345GW2-squashfs-cfe.bin
openwrt-96348GW-10-jffs2-128k-cfe.bin
openwrt-96348GW-10-jffs2-64k-cfe.bin
openwrt-96348GW-10-squashfs-cfe.bin
openwrt-96348GW-11-jffs2-128k-cfe.bin
openwrt-96348GW-11-jffs2-64k-cfe.bin
openwrt-96348GW-11-squashfs-cfe.bin
openwrt-96348GW-A-jffs2-128k-cfe.bin
openwrt-96348GW-A-jffs2-64k-cfe.bin
openwrt-96348GW-A-squashfs-cfe.bin
openwrt-96348GW-jffs2-128k-cfe.bin
openwrt-96348GW-jffs2-64k-cfe.bin
openwrt-96348GW-squashfs-cfe.bin
openwrt-96358VW-jffs2-128k-cfe.bin
openwrt-96358VW-jffs2-64k-cfe.bin
openwrt-96358VW-squashfs-cfe.bin
openwrt-AGPF-S0-jffs2-128k-cfe.bin
openwrt-AGPF-S0-jffs2-64k-cfe.bin
openwrt-AGPF-S0-squashfs-cfe.bin
openwrt-brcm63xx-jffs2-128k.trx
openwrt-brcm63xx-jffs2-64k.trx
openwrt-brcm63xx-root.jffs2-128k
openwrt-brcm63xx-root.jffs2-64k
openwrt-brcm63xx-root.squashfs
openwrt-brcm63xx-squashfs.trx
openwrt-DV201AMR-jffs2-128k-cfe.bin
openwrt-DV201AMR-jffs2-64k-cfe.bin
openwrt-DV201AMR-squashfs-cfe.bin
openwrt-F@ST2404-jffs2-128k-cfe.bin
openwrt-F@ST2404-jffs2-64k-cfe.bin
openwrt-F@ST2404-squashfs-cfe.bin
openwrt-livebox-vmlinux.elf
openwrt-livebox-vmlinux.gz
openwrt-livebox-vmlinux.lzma

what of these files i need to flash to my device?

Hi, V....

If you have a 6358 on the board, you can narrow it down to the following list:

openwrt-96358VW-jffs2-128k-cfe.bin
openwrt-96358VW-jffs2-64k-cfe.bin
openwrt-96358VW-squashfs-cfe.bin

I would start with the last one because squashfs is the most compact and the one that Broadcom recommends.

marc.

marca56 wrote:

Hi, V....

If you have a 6358 on the board, you can narrow it down to the following list:

openwrt-96358VW-jffs2-128k-cfe.bin
openwrt-96358VW-jffs2-64k-cfe.bin
openwrt-96358VW-squashfs-cfe.bin

I would start with the last one because squashfs is the most compact and the one that Broadcom recommends.

marc.

Hi, Marc. I tried to put all of these files, but have no success. For flashing i tried to use tftp but everything i've got is "timeout expired". If i put firmware via ftp i've got:

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do yo
u need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Image updating failed. The selected file contains an illegal image.  PLEASE TYPE
 'bye' or 'quit' NOW to quit ftp

Any ideas about flashing?

V...

I'm guessing that you don't know how to flash using the tftp from the CFE.

Do you have a serial console to the 6358? You will need that to stop the CFE from booting the installed image.

When the board starts up, there is a built in delay of between 1 and 3 seconds where you can hit Ctrl + C to get to the CFE prompt. Once you have the CFE prompt, you can enter a command like: flashimage openwrt-96358VW-squashfs-cfe.bin:192.168.1.10. If you setup your laptop with a fixed IP address of 192.168.1.10 and put the openwrt-96358VW-squashfs-cfe.bin in the tftp server root directory, then the flashimage command will suck down the image and you'll see some information in the telnet console and when done, the board will reboot.

There are two built in Ethernet ports on the 6358. The phy0 is the one that needs to be connected to the laptop.

marc.

imagetag for flashing kamakize from any generic broadcom stock firmware tftp or web interface.  (Alice Gate is not generic).

@florian:

  That patch doesn't work, but I have (finally) got one that does.  I can't post to Trac right now because it isn't working (502 Bad Gateway)

diff --git a/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c b/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
index d17baf2..7c82527 100644
--- a/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
+++ b/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
@@ -114,14 +114,15 @@ static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition *
         parts[curpart].name = "rootfs";
         parts[curpart].offset = rootfsaddr;
         parts[curpart].size = rootfslen;
-        if (sparelen > 0)
-            parts[curpart].size += sparelen;
+                   if (sparelen > 0)
+                parts[curpart].size += sparelen;
         curpart++;
     };
+
     parts[curpart].name = "nvram";
     parts[curpart].offset = master->size - master->erasesize;
     parts[curpart].size = master->erasesize;
-       
+
     for (i = 0; i < nrparts; i++)
         printk(KERN_INFO PFX "Partition %d is %s offset %x and length %x\n", i, parts[i].name, parts[i].offset, parts[i].size);
 
diff --git a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
index efc4f02..0de957c 100644
--- a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
+++ b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
@@ -14,13 +14,16 @@ struct bcm_tag {
     unsigned char totalLength[IMAGE_LEN];           //Total length of image
     unsigned char cfeAddress[ADDRESS_LEN];  // Address in memory of CFE
     unsigned char cfeLength[IMAGE_LEN];             // Size of CFE
-    unsigned char rootAddress[ADDRESS_LEN];         // Address in memory of rootfs
-    unsigned char rootLength[IMAGE_LEN];            // Size of rootfs
+    unsigned char cfeRootAddress[ADDRESS_LEN];         // Address in memory of rootfs (for broadcom; for wrt this is only used for flashing the image and is offset of the image)
+    unsigned char cfeRootLength[IMAGE_LEN];            // Size of rootfs
     unsigned char kernelAddress[ADDRESS_LEN];       // Address in memory of kernel
     unsigned char kernelLength[IMAGE_LEN];  // Size of kernel
     unsigned char dualImage[2];                             // Unused at present
     unsigned char inactiveFlag[2];                  // Unused at present
-    unsigned char reserved1[74];                            // Reserved area not in use
+    unsigned char reserved1[52];                            // Reserved area not in use
+    unsigned char rootAddress[ADDRESS_LEN];         // Address in memory of rootfs
+    unsigned char rootLength[IMAGE_LEN];            // Size of rootfs
+
     unsigned char imageCRC[4];                              // CRC32 of images
     unsigned char reserved2[16];                            // Unused at present
     unsigned char headerCRC[4];                             // CRC32 of header excluding tagVersion
diff --git a/target/linux/brcm63xx/image/Makefile b/target/linux/brcm63xx/image/Makefile
index b6ef968..9db2363 100644
--- a/target/linux/brcm63xx/image/Makefile
+++ b/target/linux/brcm63xx/image/Makefile
@@ -28,17 +28,16 @@ define trxalign/squashfs
 endef
 
 define Image/Build/CFE
-    # Generate the tagged image
+    # Generate the tagged image (CFE)
     $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \
         -o $(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin \
         -b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR)
 #        -b $(2) -c $(3) -e $(KERNEL_ENTRY) -l $(LOADADDR)
 
-    $(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin)
 endef
 
 define Image/Build/CFEAGPF
-    # Generate the tagged image
+    # Generate the tagged image (CFEAGPF)
     $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \
         -o $(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin \
         -b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR) \
@@ -55,6 +54,7 @@ define Image/Build/RedBoot
 endef
 
 define Image/Build/CFEOLD
+    # Generate the tagged image (CFEOLD)
     $(TOPDIR)/scripts/brcmImage.pl -t -p    \
         -b $(2) -c $(3)            \
         -k $(KDIR)/vmlinux.lzma.cfe    \
diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c
index af37992..3ada4fd 100644
--- a/tools/firmware-utils/src/imagetag.c
+++ b/tools/firmware-utils/src/imagetag.c
@@ -23,6 +23,8 @@
 #define DEFAULT_FW_OFFSET        0x10000
 #define DEFAULT_FLASH_START        0xBFC00000
 #define DEFAULT_FLASH_BS        (64 * 1024)
+#define DEADCODE                        0xDEADC0DE
+#define DEADCODE_LEN                    4
 
 /* Kernel header */
 struct kernelhdr {
@@ -47,11 +49,12 @@ struct imagetag {
     uint8_t            bigendian[2];    /*  60 -  61: "1" for big endian, "0" for little endian */
     uint8_t            imagelen[10];    /*  62 -  71: The length of all data that follows */
     struct imagecomp    cfe;        /*  72 -  93: The offset and length of CFE */
-    struct imagecomp    rootfs;        /*  94 - 115: The offset and length of the root file system */
+    struct imagecomp    rootfs;        /*  94 - 115: The offset of the start of the image and length of the root filesystem; for Broadcom firmware images this is the rootfs but causes flashing problems for WRT hence the addition of wrtrootfs */
     struct imagecomp    kernel;        /* 116 - 137: The offset and length of the kernel */
     uint8_t            dualimage[2];    /* 138 - 139: use "0" here */
     uint8_t            inactive[2];    /* 140 - 141: use "0" here */
-    uint8_t            reserved1[74];    /* 142 - 215: reserved */
+    uint8_t            reserved1[52];    /* 142 - 193: reserved */
+        struct imagecomp        wrtrootfs;      /* 193 - 215: WRT: real offset and length of the root file system */
     uint32_t        imagecrc;    /* 216 - 219: crc of the images (net byte order) */
     uint8_t            reserved2[16];    /* 220 - 235: reserved */
     uint32_t        headercrc;    /* 236 - 239: crc starting from sig1 until headercrc (net byte order) */
@@ -116,6 +119,30 @@ size_t getlen(FILE *fp)
     return retval;
 }
 
+uint32_t writepadding(FILE *padfile, size_t size, uint32_t crc) {
+  size_t paddingsize, padcount;
+  uint8_t padbuf[1024];
+  
+  for (padcount = 0; padcount < 1024; padcount++) {
+    padbuf[padcount] = 0;
+  }    
+
+  paddingsize = 0;
+
+  while (paddingsize < size) {
+    if ((size - paddingsize) > 1024) {
+      padcount = 1024;
+    } else {
+      padcount = size - paddingsize; 
+    }
+    fwrite(padbuf, sizeof(uint8_t), padcount, padfile);
+    
+    paddingsize += padcount;
+    crc = crc32(crc, padbuf, padcount);
+  }
+  return crc;
+}
+
 int tagfile(const char *kernel, const char *rootfs, const char *bin,
         const char *boardid, const char *chipid, const uint32_t fwaddr,
         const uint32_t loadaddr, const uint32_t entry,
@@ -124,9 +151,10 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
     struct imagetag tag;
     struct kernelhdr khdr;
     FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile;
-    size_t kerneloff, kernellen, rootfsoff, rootfslen, read;
+    size_t kerneloff, kernellen, rootfsoff, rootfslen, read, cferootfsoff, cferootfslen, imagelen, imageoff, rootfspaddingsize, origrootfslen;
     uint8_t readbuf[1024];
     uint32_t crc;
+    const uint32_t deadcode = htonl(DEADCODE);
 
     memset(&tag, 0, sizeof(struct imagetag));
 
@@ -154,9 +182,17 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
         fprintf(stderr, "Unable to open output file \"%s\"\n", bin);
         return 1;
     }
+    /* Initialize CRC */
+    crc = IMAGETAG_CRC_START;
+
+    /* Initialize image length calculations */
+    imagelen = 0;
+    cferootfslen = 0;
 
     /* Build the kernel address and length (doesn't need to be aligned, read only) */
     kerneloff = fwaddr + sizeof(tag);
+    imageoff = kerneloff;
+    cferootfsoff = imageoff;
     kernellen = getlen(kernelfile);
 
     /* Build the kernel header */
@@ -167,17 +203,21 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
     /* Increase the kernel size by the header size */
     kernellen += sizeof(khdr);
 
+    imagelen += kernellen;
+
     /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */
     rootfsoff = kerneloff + kernellen;
     rootfsoff = (rootfsoff % flash_bs) > 0 ? (((rootfsoff / flash_bs) + 1) * flash_bs) : rootfsoff;
-    rootfslen = getlen(rootfsfile);
+    origrootfslen = getlen(rootfsfile);
+    rootfslen = origrootfslen;
     rootfslen = (rootfslen % flash_bs) > 0 ? (((rootfslen / flash_bs) + 1) * flash_bs) : rootfslen;
+    cferootfslen = rootfslen;
 
     /* Seek to the start of the kernel */
     fseek(binfile, kerneloff - fwaddr, SEEK_SET);
 
     /* Write the kernel header */
-    crc = crc32(IMAGETAG_CRC_START, (uint8_t*)&khdr, sizeof(khdr));
+    crc = crc32(crc, (uint8_t*)&khdr, sizeof(khdr));
     fwrite(&khdr, sizeof(khdr), 1, binfile);
 
     /* Write the kernel */
@@ -187,16 +227,39 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
         fwrite(readbuf, sizeof(uint8_t), read, binfile);
     }
 
+    /* Write padding from end of kernel to start of RootFS needed so that
+     * RootFS starts on and erase boundary, and calculate its CRC 
+     */
+    rootfspaddingsize = rootfsoff - (kerneloff + kernellen );
+    imagelen += rootfspaddingsize;
+    /* FIXME: Don't use this CRC for Alice Gate */
+    crc = writepadding(binfile, rootfspaddingsize, crc);
+
     /* Write the RootFS */
-    fseek(binfile, rootfsoff - fwaddr, SEEK_SET);
     while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
         read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
-        /*
-         * TODO: Is this necessary ?
-         * crc = crc32(crc, readbuf, read);
-         */
+        /* FIXME: Don't do this for Alice Gate */
+        crc = crc32(crc, readbuf, read);
+        
         fwrite(readbuf, sizeof(uint8_t), read, binfile);
     }
+    imagelen += origrootfslen;
+
+    /* Write the ending padding and end-of-filesystem marker for RootFS so
+     * that RootFS ends on an erase boundary, and calculate its CRC 
+     */
+
+    /* FIXME: Don't use the CRC for Alice Gate */
+    crc = writepadding(binfile, rootfslen - origrootfslen, crc);
+    imagelen += rootfslen - origrootfslen;
+    cferootfslen += rootfslen - origrootfslen;
+
+    /* Write end-of-filesystem marker */
+    /* FIXME: Don't use this CRC for Alice Gate */
+    crc = crc32(crc, (uint8_t*)&deadcode, DEADCODE_LEN);
+    fwrite((uint8_t*)&deadcode, sizeof(uint8_t), DEADCODE_LEN, binfile);
+    imagelen += DEADCODE_LEN;
+    cferootfslen += DEADCODE_LEN;
 
     /* Close the files */
     fclose(kernelfile);
@@ -209,7 +272,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
     strcpy(tag.chipid, chipid);
     strcpy(tag.boardid, boardid);
     strcpy(tag.bigendian, "1");
-    sprintf(tag.imagelen, "%lu", kernellen + rootfslen);
+    sprintf(tag.imagelen, "%lu", imagelen);
 
     /* We don't include CFE */
     strcpy(tag.cfe.address, "0");
@@ -221,8 +284,10 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
     }
 
     if (rootfsfile) {
-        sprintf(tag.rootfs.address, "%lu", rootfsoff);
-        sprintf(tag.rootfs.len, "%lu", rootfslen);
+        sprintf(tag.rootfs.address, "%lu", cferootfsoff);
+        sprintf(tag.rootfs.len, "%lu", cferootfslen);
+        sprintf(tag.wrtrootfs.address, "%lu", rootfsoff);
+        sprintf(tag.wrtrootfs.len, "%lu", rootfslen);
     }
 
     tag.imagecrc = htonl(crc);

(Last edited by cshore on 14 Apr 2009, 12:11)

Sorry, posts 351 to 350 are missing from our archive.