OpenWrt Forum Archive

Topic: Bootloader/Image for a DLink DWL-2100AP

The content of this topic has been archived between 26 Mar 2018 and 5 May 2018. Unfortunately there are posts – most likely complete pages – missing.

Hi bitbucket,

Thank you for your comments and hints.

bitbucket wrote:

(on merging the fis and fconfig) AFAIK, it is default in redboot.

Perhaps it is for certain platforms, but it's certainly not the case for the ap51 (I'm using the reference redboot with your patches and mine). But it's otherwise a good idea keeping the fis and fconfig together. Actually, with a little tweaking it's probably possible to merge all the config blocks into a single one. This would required copying the whole block to ram each time a config were updated, but since it's not done very often, it shouldn't be a problem.

bitbucket wrote:

I'm using redboot only for loading kernel from flash or from network, so I have removed FIS, configuration (it is hardcoded) and other debugging stuff from redboot.

The fis is very convenient for prototyping, but it's probably unnecessary for production. How do you get rid of the debugging stuff?

bitbucket wrote:

I've got different value: about ~100kb between gzip and lzma compressed kernel.

Of course that figure varies depending on the kernel config options and I'm probably lucky getting 25%.

bitbucket wrote:

(on detecting code length) ... It is simple, because of flat memory model !

I tried that, but at least on one occasion I got the wrong numbers because apparently the linker or gcc had relocated the code, changing the order of each procedure. Do you know how to prevent this from happening?

bitbucket wrote:

(on detecting whether code runs from ROM) This can be made by address value in epc ($14)

This probably works, but I was looking for a more portable way. Aren't there any global variables in redboot that tell you where the ROM is? Then because of the flat memory model it should be just a matter of comparing the pointer of the current function with those values, right?

Well, now to a completely different issue. I was thinking whether it would be possible to completely replace the original firmware with redboot and openwrt using just the web interface. I think this could be done in stages: first an intermediate image is loaded that will install redboot and a minimal kernel with a web interface. Then this could be used to load a final redboot and openwrt. It would be convenient and would avoid opening the case and so it's less time-consuming. We have over 200 of these ap's in the field and opening each of them is certainly not a good prospect.

Do you think this is possible?

ramcheck

Hi erebus,

erebus wrote:

Unfortunately I had to revert it to original ap43 version because of awfully long TFTP downloading time. It takes more than five minutes to load ramdisked linux compared to 13 seconds I've had before.
May be your 2 to 5 minutes decompression time is somehow related to this? At least I havn't noticed any slowdown with gzipped kernel on ap43 - it starts almost instantly.

Thanks for your testing and feedback. I was suspecting there was something wrong with the ap51 setup. Most things seem much slower than they should be, but my times are not so long as the ones you describe. I'll be investigating this issue more closely before too long.

In any case, AFAIK rom is significantly slower than ram and this should reflect in longer decompression times. Unless, of course, the code was copied to ram first.

ramcheck

Hi guys,

bitbucket wrote:
erebus wrote:

Also I don't thoroughly understand how bootblocks are described. Are those values sizes or offsets or something else?

bootblocks: <offset of 1st block>, <offset of 2nd block> and so on. i.e. these values are offests by which it is possible to erase sector.

Isn't it more like <first block base> <block-length> <block-length> ... etc? In any case the device geometry is available in the CFI and this is a standard in the amd/fujitsu world, so why do we need a hard-coded table?

ramcheck

ramcheck wrote:

Actually, with a little tweaking it's probably possible to merge all the config blocks into a single one. This would required copying the whole block to ram each time a config were updated, but since it's not done very often, it shouldn't be a problem.

It may help, when it will be not enouhg space in flash for software.

ramcheck wrote:
bitbucket wrote:

I'm using redboot only for loading kernel from flash or from network, so I have removed FIS, configuration (it is hardcoded) and other debugging stuff from redboot.

The fis is very convenient for prototyping, but it's probably unnecessary for production. How do you get rid of the debugging stuff?

If kernel can't boot from flash, I'll boot stable version from ram via tftp and use it to replace kernel.

bitbucket wrote:

I've got different value: about ~100kb between gzip and lzma compressed kernel.

Of course that figure varies depending on the kernel config options and I'm probably lucky getting 25%.

ramcheck wrote:
bitbucket wrote:

(on detecting code length) ... It is simple, because of flat memory model !

I tried that, but at least on one occasion I got the wrong numbers because apparently the linker or gcc had relocated the code, changing the order of each procedure. Do you know how to prevent this from happening?

Check compiler's assembler output (-S), because linker does not change function layout inside one object (.o). If your function and XXX_end function are in one module - it should work: linker does not change their locations.
Also, you may use asm() to make symbol with function size like this:

#include <stdlib.h>

void test(void) {
  printf("ddd\n");
  printf("ddd\n");
}

asm("\ntest_size = . - test\n");

int main(void) {
  extern int *test_size;
  printf("size=%d\n",&test_size);
  return 0;
}
ramcheck wrote:

This probably works, but I was looking for a more portable way. Aren't there any global variables in redboot that tell you where the ROM is? Then because of the flat memory model it should be just a matter of comparing the pointer of the current function with those values, right?

Check files in /ecos-2.0/packages/hal/mips/<platform>/v2_0/include/pkgconf

ramcheck wrote:

Well, now to a completely different issue. I was thinking whether it would be possible to completely replace the original firmware with redboot and openwrt using just the web interface. I think this could be done in stages: first an intermediate image is loaded that will install redboot and a minimal kernel with a web interface. Then this could be used to load a final redboot and openwrt. It would be convenient and would avoid opening the case and so it's less time-consuming. We have over 200 of these ap's in the field and opening each of them is certainly not a good prospect.

Do you think this is possible?

It is not possible to change bootloader from original firmware - it have no access to this part of flash from vxworks.

The easyest way is: make temporary console cable, connect it to device, from original bootloader command prompt load kernel+ramdisk via tftp, update flash from kernel using mtd. It is about ~10min per device, I think.

ramcheck wrote:

so why do we need a hard-coded table?

Because driver in rebdoot can't read geometry from chip, linux and jtag read it from chip and all works fine.

Hi bitbucket,

Thank you for all the feedback and infos. I'll get back to development/testing later today.

ramcheck

bitbucket wrote:

Because lpt port not so fast, and also you have to use lower jtag data clock speed for unbuffered cable because interference (buffered cable works better), and both cables: wiggler or dlc5 not use dma.

That's clear. I wonder what cable and software was used to achieve results posted in wiki. After all the DLC5 cable is ubelieveable slow compared to those, so I think there can be some misconfiguration in my setup.

bitbucket wrote:

May be these values are wrong ? because by default (for ihis platform) kernel starts from 0x80041000 , and entry point is at 0x8021e000

Thanks for a hint. "exec -b 0x80041000" did the job, but the kernel complains about unexpected IRQ #0 when I type something on console. I'll try to investigate this issue and why RedBoot decided the kernel base to be at 0x80080000 even this address doesn't figure in headers according to readelf output.

ramcheck wrote:

I was thinking whether it would be possible to completely replace the original firmware with redboot and openwrt using just the web interface. I think this could be done in stages

There are some threads in russian about hacking DWL-2100AP, but the discussion inevitable comes to arguing about BlueBox (the firmware in similiar devices). Someone even wrote tfp unpacker to extract files from original firmware, but it seems nobody had reverse-engineered APIMG1 file that VxWorks loader boots by default.
I don't know if that's of any use, but Linksys WRT54GS router starting from rev.5 is shipped with VxWorks and multistaged process of reflashing it to linux is described here.

Hi ramcheck,

I have tested your new redboot with lzma compression support.
I have loaded on the flash openwrt with lzma compression
But when i try to load it in memory...

fis load -d vmlinux.bin.l7
decompression error: incorrect gzip header

What's wrong?

Wellcome back bitbucket wink

(Last edited by ramponis on 2 Jul 2007, 15:46)

erebus wrote:

That's clear. I wonder what cable and software was used to achieve results posted in wiki. After all the DLC5 cable is ubelieveable slow compared to those, so I think there can be some misconfiguration in my setup.

I've tested DLC5 (used to unbrick linksys'es) and WIGGLER cables. Because my DLC5 cable is unbuffered I'm using WIGGLER, which is buffered and works fine at high clock rates.

erebus wrote:

Thanks for a hint. "exec -b 0x80041000" did the job, but the kernel complains about unexpected IRQ #0 when I type something on console. I'll try to investigate this issue and why RedBoot decided the kernel base to be at 0x80080000 even this address doesn't figure in headers according to readelf output.

I had such a problem when I started to port redboot to 2100AP. Try to 'go <startup addr>' in redboot - may be it helps. But redboot must to load elf kernel at the location, which set in elf file. When I'm loading kernel from net - it works right.

erebus wrote:

There are some threads in russian about hacking DWL-2100AP, but the discussion inevitable comes to arguing about BlueBox (the firmware in similiar devices). Someone even wrote tfp unpacker to extract files from original firmware, but it seems nobody had reverse-engineered APIMG1 file that VxWorks loader boots by default.

BlueBox by vector from the Ukraine ? It is vxworks driven firmware, so reflash is very simple. Btw, if anybody want to test it - free version at http://tchk.net/download/ffw.zip . I'm never use this firmware, but some people like it.

erebus wrote:

I don't know if that's of any use, but Linksys WRT54GS router starting from rev.5 is shipped with VxWorks and multistaged process of reflashing it to linux is described here.

If you have one-two devices like linksys with vxworks - it is possible to reflash them, but when there are about 500-600 devices, it is too many for reflash using jtag.

(Last edited by bitbucket on 2 Jul 2007, 16:57)

Hi ramponis,

Just like the foneras, you use -l switch for lzma decompression. wink

ramcheck

ramponis wrote:

Hi ramcheck,

I have tested your new redboot with lzma compression support.
I have loaded on the flash openwrt with lzma compression
But when i try to load it in memory...

fis load -d vmlinux.bin.l7
decompression error: incorrect gzip header

What's wrong?

Wellcome back bitbucket wink

Thank you ramcheck

Hey bitbucket,

bitbucket wrote:

Because my DLC5 cable is unbuffered I'm using WIGGLER, which is buffered and works fine at high clock rates.

What clock rates have you tested with the WIGGLER. I have one, but it's doesn't seem faster than my older unbuffered cable. A you using openwince-jtag?

Another question: how can you do a hard reset with jtag?

ramcheck

Hey guys,

This is how you put a function in ram. At the function definition, simply declare it like:

int  some_function(void* arg1, unsigned int arg2)
    __attribute__ ((section (".2ram.some_function")));

Then just call your function as usual.

ramcheck

ramcheck wrote:

What clock rates have you tested with the WIGGLER. I have one, but it's doesn't seem faster than my older unbuffered cable. A you using openwince-jtag?

Yes, I'm using openwince-jtag, and clock frequency is 0 (i.e. maximum possible).
The difference between buffered and unbuffered cables is maximum cable length, at which jtag works without errors. I have a lot of electronics at my workplace, so for sure that all data from jtag are correct I had made buffered WIGGLER cable.

ramcheck wrote:

Another question: how can you do a hard reset with jtag?

OCD commander have this function, and it works. But I like to unplug power supply and plug it back.
All debugging for redboot I've done from windows version of ocd commander. Also, some of redboot builds I had loaded via jtag directly to RAM. It is fast enought.

ramcheck wrote:

This is how you put a function in ram. At the function definition, simply declare it like:

int  some_function(void* arg1, unsigned int arg2)
    __attribute__ ((section (".2ram.some_function")));

Then just call your function as usual.

To use this definition correctly in your program scope you have to edit linker's script (.lds file) to set address space for your section ".2ram.some_function". And don't forget, that in RAW image you have no symbol table (like in elf file), so you can't access your section or any symbol by name.

But, it is not possible to make raw image of such elf file for flash.

I've made redboot from 2 parts: first is part of original bootloader, which check system, setup system and unpack RAM version of redboot from flash to RAM. redboot is loaded to the end of ram, to get linux kernel loaded as it like. After kernel is started I don't need redboot code any more - it overrided by kernel's/user's data. In this case all RAM are used by kernel, and redboot works fast enough from RAM (it loads 3Mb image from tftp in seconds), also it have small size in flash because compression.

bitbucket wrote:
ramcheck wrote:

This is how you put a function in ram. At the function definition, simply declare it like:

int  some_function(void* arg1, unsigned int arg2)
    __attribute__ ((section (".2ram.some_function")));

Then just call your function as usual.

To use this definition correctly in your program scope you have to edit linker's script (.lds file) to set address space for your section ".2ram.some_function". And don't forget, that in RAW image you have no symbol table (like in elf file), so you can't access your section or any symbol by name.

But, it is not possible to make raw image of such elf file for flash.

Why, it seems to have worked for me. No compilation or execution errors/warnings whatsoever, and I'm getting times comparable to when I was copying the code to ram. My guess is that redboot has it's own resolver/loader. It must have for otherwise all the flash stuff, which uses this principle, would not work. Anyway it seems that the .lds files are inexistent and/or they're not used in redboot.

Redboot is for the most part unnecessary, however makes certain things more convenient, at the expense of three flash blocks or less. Not so bad.

ramcheck

ramcheck wrote:

Why, it seems to have worked for me. No compilation or execution errors/warnings whatsoever, and I'm getting times comparable to when I was copying the code to ram. My guess is that redboot has it's own resolver/loader.

I did not find where in redboot code section "2ram" is copied to RAM. It needs more investigations for me to understand how it works. Thank you for this information.

ramcheck wrote:

It must have for otherwise all the flash stuff, which uses this principle, would not work. Anyway it seems that the .lds files are inexistent and/or they're not used in redboot.

.lds (or .ld) files are needed to link code correct. Main file is placed at buildXXX_PPP/install/lib/target.ld

ramcheck wrote:

Redboot is for the most part unnecessary, however makes certain things more convenient, at the expense of three flash blocks or less. Not so bad.

It is usable only for developer, not user. I need more flash for working system, which I will use evry day or week, and does not need any extra features in bootloader, which is used once a year to recover broken firmware.

A few years ago I'd made linux run on adsl modem with conexant SoC. There were no bootloader at all - only kernel which setup hardware to run linux kernel at start and filesystem.Flash was reprogrammed via usb.

Hi,

I've found why RedBoot assumes kernel base to be at 0x80080000. It is just the value of CYGDAT_REDBOOT_MIPS_LINUX_BOOT_ARGV_ADDR option defined in packages/hal/mips/arch/v2_0/cdl/hal_mips.cdl. It's never redefined anywhere else so it's taken by default. This address is used to store user and machine-specific parameters and then passed to kernel. The corresponding function is do_exec in packages/hal/mips/arch/v2_0/src/redboot_linux_exec.c.
WARNING!If you don't take care about that, you'll get a hidden kernel corruption since 0x80080000 points inside linux code. The workaround that bitbucket suggested is to use "go" instead of "exec".
I don't know what the correct solution is. Defining this option in packages/hal/mips/ap43/v2_0/misc/redboot_ROM.ecm as inferred_value 0x80041000 doesn't help, because initial jump gets overwritten and I've had to specify correct entry point every time. That's inconvenient because this address can change from one kernel to another. The most funny part is that's impossible to pass parameters anyway - the kernel ingores them on this platform hmm

erebus wrote:

I've found why RedBoot assumes kernel base to be at 0x80080000.

Redboot have to determine kernel loading address from ELF file, like it does when loading file from network.

bitbucket wrote:

Redboot have to determine kernel loading address from ELF file, like it does when loading file from network.

RedBoot loads kernel to correct address. The problem is with "exec" command and I've encountered it exactly during booting trunk kernel from network, though it affects FIS stored kernels too. Take a look what RedBoot says after you order it to "exec" but before it jumps to Linux. Base address equals to 0x80080000 independent of what is in ELF header. You may want to examine redboot_linux_exec.c to see that redboot writes some parameters (memory size, console port setup, MAC address) to this address in order to pass them to kernel.

A not-so-quick test:
1. Load kernel from network and do "exec". Then do "reboot" to get back into RedBoot. Examine interesting region with "dump -b 0x80080000 -l 0x100". You can even see some human-readable strings like "memsize" and "modetty" there. Load kernel again and do "exec 0x80041000". Kernel boots ok.
2. Load kernel from network and do "exec -b 0x80041000". The do "reboot" to get back into RedBoot. Examine interesting regions with "dump -b 0x80080000 -l 0x100" and "dump -b 0x80041000 -l 0x100". You can see that kernel parameters moved to second location. Load kernel again and do "exec -b 0x80041000 0x80041000". RedBoot panics because parameters has overwritten initial jump.
3. Disassemble kernel with debug symbols (located in build_mips/linux/vmlinux) via objdump. Go to 0x80080000 - you'll probably end up within some kernel function.

I think it's worth to bear in mind these side-effects of "exec" command.

bitbucket wrote:
ramcheck wrote:

so why do we need a hard-coded table?

Because driver in rebdoot can't read geometry from chip, linux and jtag read it from chip and all works fine.

A nice cfi-compliant driver is in the oven and it looks promising... preliminary results below. The only critical information that is a bit harder to obtain from the chips is the geometry of the boot blocks. For that, it seems that the PRI (which is optional) is required. At the present stage, my driver should be able to recover that information from PRI versions 1.0 throug 1.3. This covers all the flash devices that have been seen in the DWL-2100AP's.

Good hacking,
ramcheck

RedBoot startup
Detected CFI-compliant device
Device size 0x00400000
Number of erase regions: 2
Erase region 1, block size=0x00010000, count=63
Erase region 2, block size=0x00002000, count=8
Block size 0x00010000, block_count 64
Primary extended information version 1.0.
Boot blocks type: 2
Flash block table:
0x00000000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
Flash initialization sucessfull
...
Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x80010000-0x81000000, 0x806c1878-0x807d1ce0 available
FLASH: 0xbfc00000 - 0xbffe0000, 62 blocks of 0x00010000 bytes each.
RedBoot>

A RAM image for testing is available here
It's very easy to test from redboot/tftp and it should not brick your unit (although I offer absolutely no warranties):

RedBoot> load redboot.img
Entry point: 0x80680000, address range: 0x80680000-0x806ac318
RedBoot> exec
...

Beware: this think may shrink your kids and scare your dog! Please leave your feedback.

(Last edited by ramcheck on 4 Jul 2007, 02:23)

Hi ramcheck,

I've tested your version. Seems like it works!

RedBoot> l redboot.img
Entry point: 0x80680000, address range: 0x80680000-0x806ac330
RedBoot> g
+
RedBoot startup
Detected CFI-compliant device
Device size 0x00400000
Number of erase regions: 2
Erase region 1, block size=0x00002000, count=8
Erase region 2, block size=0x00010000, count=63
Block size 0x00010000, block_count 64
Primary extended information version 1.3.
Boot blocks type: 2 (2=bottom, 3=top)
Flash block blocks layout:
0x00000000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
Flash initialization sucessfull
Ethernet eth0: MAC address 00:17:xx:xx:xx:xx
IP: 10.10.10.111/255.255.255.0, Gateway: 10.10.10.7
Default server: 10.10.10.7, DNS server IP: 0.0.0.0

RedBoot(tm) bootstrap and debug environment [RAM]
Non-certified release, version v2_0 - built 22:19:06, Jul  3 2007
With changes made by Waldeck Schutzer <waldeck@dm.ufscar.br>


Copyright (C) 2000, 2001, 2002, Red Hat, Inc.

RAM: 0x80010000-0x81000000, 0x806c1888-0x807d1ce0 available
FLASH: 0xbfc00000 - 0xbffe0000, 62 blocks of 0x00010000 bytes each.
RedBoot> fis init -f
About to initialize [format] FLASH image system - continue (y/n)? y
*** Initialize FLASH Image System
... Erase from 0xbfc30000-0xbffc0000: ..........................................
...............
... Erase from 0xbffd0000-0xbffd0000:
... Erase from 0xbffe0000-0xbffe0000:
... Erase from 0xbffd0000-0xbffe0000: .
... Program from 0x80fef000-0x80fff000 at 0xbffd0000: .
RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0xBFC00000  0xBFC00000  0x00030000  0x00000000
RedBoot config    0xBFFC0000  0xBFFC0000  0x00001000  0x00000000
FIS directory     0xBFFD0000  0xBFFD0000  0x00010000  0x00000000

That's a great work and really adds convinience.
As the last version of RedBoot has been released 3 years ago, I wonder what it's current development status is.

(Last edited by erebus on 4 Jul 2007, 10:46)

Hi erebus,

Thank you for taking your time testing my driver. I just have to parse a few fields in the Common Flash Interface data. It should work for the chips in the DWL2100AP and probably on other boards as well, provided that the flash chip is CFI-compliant versions 1.0 through 1.3. It's not a full CFI driver though, so we can't expect it to work everywhere.

I can see from your logs that you have a different chip than mine. cool If I added manufacturer/id parsing, would you mind testing it again? I wonder if it'll still work for an upper boot block device.

erebus wrote:

Hi ramcheck,

I've tested your version. Seems like it works!

That's a great work and really adds convinience.
As the last version of RedBoot has been released 3 years ago, I wonder what it's current development status is.

Well RedBoot development may have stalled as a whole, but there's always room for a few improvements. wink I wonder if the stuff I'm doing is of any interest to them.

Cheers,
ramcheck

Edit: The above changes are available here.

(Last edited by ramcheck on 4 Jul 2007, 19:36)

Hi ramcheck,

I've tried your bootloader. Here's the output:

RedBoot startup

Detected flash, manufacturer=0x0001, id codes=(0x7e 0x1a 0x00)
Detected CFI-compliant device
Device size 0x00400000
Number of erase regions: 2
Erase region 1, block size=0x00002000, count=8
Erase region 2, block size=0x00010000, count=63
Block size 0x00010000, block_count 64
Primary extended information version 1.3.
Boot blocks type: 2 (2=bottom, 3=top)
Flash block blocks layout:
0x00000000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
0x00002000
Flash initialization sucessfull

Onboard flash chip is Spansion S29GL032M90TFIR4.

Hi erebus,

Thank you for the test.

erebus wrote:

Onboard flash chip is Spansion S29GL032M90TFIR4.

That's what I was going to say if you hadn't said so. I feel encouraged by the fact that, although I have built and tested on a completely different chip, the code also works fine for your chip. Now I have to do a some code polishing, remove the debugging stuff and post the patches somewhere. Unfortunately I'm having difficulties with my ISP at this moment and I must find an alternative place to host my stuff.

ramcheck

Edit: I'm working on some parts of the driver that are still hardwired, like the support for the different operation modes, serial/parallel arrangement, etc. I should soon have a driver that relies solely on the CFI data and hence should work everywhere. Patience makes the perfect...

(Last edited by ramcheck on 5 Jul 2007, 23:46)

Sorry, posts 151 to 150 are missing from our archive.