embedded x86

Had anybody here tried to embed anything for a x86 board with paged flash
memory?
I have Embedding Tools here but I still could not find out how to do this.
I was checking the board I am working on, and I realized that I may need a
warm boot. Is it enough to just create an image through mkifs and save to
flash memory? If not so, what do I need to do besides that, so that I can
create a flash image?


Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

Had anybody here tried to embed anything for a x86 board with paged flash
memory?
I have Embedding Tools here but I still could not find out how to do this.
I was checking the board I am working on, and I realized that I may need a
warm boot. Is it enough to just create an image through mkifs and save to
flash memory? If not so, what do I need to do besides that, so that I can
create a flash image?



Regards,

Ricardo Kazumi Ashikawa

Hello,

Paged flash is indeed supported by our embedding toolkit. If you have the
latest Board Support Package (BSP) for x86, it contains source code for
a flash filesystem driver for the AMD SC400 evaluation board. This code
can be used as a starting point for developing your own custom flash
driver.

Within this flash source you will find a file called f3s_sc400_page.c,
which contains the paging routine. This routine is required in all QNX 6
flash drivers, whether the flash is linearly mapped, or paged. It is
here that you would insert the hardware-specific code necessary to hit
the page configuration registers of your hardware.

Developing a flash driver that supports paged flash will allow you to
create and use a QNX 6 flash filesystem on your hardware. However, you
mentioned placing a boot image, created with mkifs, in flash. The placing
of the image can be done with the flash driver, but if you intend to boot
that image from an Initial Program Loader (IPL) that you develop yourself,
paging code will also have to be inserted into the IPL, to allow the boot
image to be copied from paged flash to DRAM.


Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

Hi Dave!
What about QNX6 BSP for OCTAGON5066 ?

Gregory V.Zaytcev

Hi,

Thanks for your response.
Here is what I want to do, and I would like to know if it is possible.
We have a memory mapped flash that works as a extended BIOS, that is, it has
extended BIOS identifier (0x55aa).
I want it to intercept BIOS call to floppy drive A:, and then copy a program
from flash to RAM, and finally run this code. This code would copy
compressed image created by mkifs and boot QNX. Is it possible?
Another possibility would be to have a code inside extended BIOS that would
copy compressed image created by mkifs from flash to RAM and boot. Is it
possible?
How should I do either way? If I just copy from flash to RAM and “jump” to
the begining of the code on RAM, will it work?


Regards,

Ricardo Kazumi Ashikawa


Hello,

Paged flash is indeed supported by our embedding toolkit. If you have the
latest Board Support Package (BSP) for x86, it contains source code for
a flash filesystem driver for the AMD SC400 evaluation board. This code
can be used as a starting point for developing your own custom flash
driver.

Within this flash source you will find a file called f3s_sc400_page.c,
which contains the paging routine. This routine is required in all QNX 6
flash drivers, whether the flash is linearly mapped, or paged. It is
here that you would insert the hardware-specific code necessary to hit
the page configuration registers of your hardware.

Developing a flash driver that supports paged flash will allow you to
create and use a QNX 6 flash filesystem on your hardware. However, you
mentioned placing a boot image, created with mkifs, in flash. The placing
of the image can be done with the flash driver, but if you intend to boot
that image from an Initial Program Loader (IPL) that you develop yourself,
paging code will also have to be inserted into the IPL, to allow the boot
image to be copied from paged flash to DRAM.

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

Hi,

Thanks for your response.
Here is what I want to do, and I would like to know if it is possible.
We have a memory mapped flash that works as a extended BIOS, that is, it has
extended BIOS identifier (0x55aa).
I want it to intercept BIOS call to floppy drive A:, and then copy a program
from flash to RAM, and finally run this code. This code would copy
compressed image created by mkifs and boot QNX. Is it possible?
Another possibility would be to have a code inside extended BIOS that would
copy compressed image created by mkifs from flash to RAM and boot. Is it
possible?
How should I do either way? If I just copy from flash to RAM and “jump” to
the begining of the code on RAM, will it work?

Yes, it’s possible, and the method we use is a combination of the two
possibilities that you mentioned. The x86 BSP that I mentioned earlier
also contains sample source for generating a BIOS extension IPL which
allows the SC400 evaluation board to boot from flash. Very little of the
code is specific to the SC400, and it will work for any BIOS system which
provides a facility for executing a user-generated BIOS extension.
Basically, it goes like this;

  1. Copy the code from /usr/src/bsp-6.1.0/x86/sc400/src/hardware/ipl/boards/sc400_ext
    to some other directory, ex.
    /usr/src/bsp-6.1.0/x86/my_bsp/src/hardware/ipl/boards/my_bios_ext

  2. remove the code from main.c which deals with setting up the SC400’s
    flash chip selects; you probably don’t need it on your hardware.

  3. make the binary IPL

  4. Run the mkrom utility on the resultant binary (NOTE: mkrom didn’t get
    shipped with QNX 6.1.0; I’ll put a copy in the R&D developer’s corner
    of qdn.qnx.com - go to http://qdn.qnx.com, click on “experimental
    software”, and look for mkrom under “new stuff”). mkrom pads the IPL
    out to a 1K boundary, and then fills in the first 6 bytes of the IPL
    with the 55AA BIOS extension signature, as well as the size and
    checksum bytes, and the proper jump instruction.

ex.
mkrom ipl-my_bios_ext

  1. Place the BIOS extension that you’ve created into your flash, such
    that it will get executed by your BIOS.

Here’s what it does, in general;

-when it gets executed, it re-vectors the BIOS INT19 disk boot call
to INT 0xF8

-copies itself to the area of DRAM just under 1M. For example, if the
size of the BIOS extension was 6k, it will copy itself to address
1042432 (1M - 6k).

-transfers execution from flash/ROM to DRAM

-exits, returning control to the BIOS

Now, when the BIOS has finished the rest of its work, it calls int19
to boot from disk, but your code gets executed instead. When it returns
to the IPL, c main() of the IPL is called, which then calls our IPL library
functions for booting from flash: image_scan_ext(), image_setup_ext(), and
image_start_ext(). These functions assume linearly mapped flash is available,
so if you’re using paged flash, you’ll need to modify the routines to page
the flash.



Regards,

Ricardo Kazumi Ashikawa



Hello,

Paged flash is indeed supported by our embedding toolkit. If you have the
latest Board Support Package (BSP) for x86, it contains source code for
a flash filesystem driver for the AMD SC400 evaluation board. This code
can be used as a starting point for developing your own custom flash
driver.

Within this flash source you will find a file called f3s_sc400_page.c,
which contains the paging routine. This routine is required in all QNX 6
flash drivers, whether the flash is linearly mapped, or paged. It is
here that you would insert the hardware-specific code necessary to hit
the page configuration registers of your hardware.

Developing a flash driver that supports paged flash will allow you to
create and use a QNX 6 flash filesystem on your hardware. However, you
mentioned placing a boot image, created with mkifs, in flash. The placing
of the image can be done with the flash driver, but if you intend to boot
that image from an Initial Program Loader (IPL) that you develop yourself,
paging code will also have to be inserted into the IPL, to allow the boot
image to be copied from paged flash to DRAM.

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

Dave:

This is the x86 Board Support Package (BSP) that costs and additional
$5000+?


Jeff Maass jmaass@columbus.rr.com Located near Columbus Ohio
USPSA # L-1192 NROI/CRO Amateur Radio K8ND
Maass’ IPSC Resources Page: http://home.columbus.rr.com/jmaass


“Dave Green” <dgreen@qnx.com> wrote in message
news:9pft18$kvg$1@nntp.qnx.com

Ricardo Kazumi Ashikawa <> ashikawa@dixtal.com.br> > wrote:
Hi,

Thanks for your response.
Here is what I want to do, and I would like to know if it is possible.
We have a memory mapped flash that works as a extended BIOS, that is, it
has
extended BIOS identifier (0x55aa).
I want it to intercept BIOS call to floppy drive A:, and then copy a
program
from flash to RAM, and finally run this code. This code would copy
compressed image created by mkifs and boot QNX. Is it possible?
Another possibility would be to have a code inside extended BIOS that
would
copy compressed image created by mkifs from flash to RAM and boot. Is it
possible?
How should I do either way? If I just copy from flash to RAM and “jump”
to
the begining of the code on RAM, will it work?

Yes, it’s possible, and the method we use is a combination of the two
possibilities that you mentioned. The x86 BSP that I mentioned earlier
also contains sample source for generating a BIOS extension IPL which
allows the SC400 evaluation board to boot from flash. Very little of the
code is specific to the SC400, and it will work for any BIOS system which
provides a facility for executing a user-generated BIOS extension.
Basically, it goes like this;

  1. Copy the code from
    /usr/src/bsp-6.1.0/x86/sc400/src/hardware/ipl/boards/sc400_ext
    to some other directory, ex.
    /usr/src/bsp-6.1.0/x86/my_bsp/src/hardware/ipl/boards/my_bios_ext

  2. remove the code from main.c which deals with setting up the SC400’s
    flash chip selects; you probably don’t need it on your hardware.

  3. make the binary IPL

  4. Run the mkrom utility on the resultant binary (NOTE: mkrom didn’t get
    shipped with QNX 6.1.0; I’ll put a copy in the R&D developer’s corner
    of qdn.qnx.com - go to > http://qdn.qnx.com> , click on “experimental
    software”, and look for mkrom under “new stuff”). mkrom pads the IPL
    out to a 1K boundary, and then fills in the first 6 bytes of the IPL
    with the 55AA BIOS extension signature, as well as the size and
    checksum bytes, and the proper jump instruction.

ex.
mkrom ipl-my_bios_ext

  1. Place the BIOS extension that you’ve created into your flash, such
    that it will get executed by your BIOS.

Here’s what it does, in general;

-when it gets executed, it re-vectors the BIOS INT19 disk boot call
to INT 0xF8

-copies itself to the area of DRAM just under 1M. For example, if the
size of the BIOS extension was 6k, it will copy itself to address
1042432 (1M - 6k).

-transfers execution from flash/ROM to DRAM

-exits, returning control to the BIOS

Now, when the BIOS has finished the rest of its work, it calls int19
to boot from disk, but your code gets executed instead. When it returns
to the IPL, c main() of the IPL is called, which then calls our IPL
library
functions for booting from flash: image_scan_ext(), image_setup_ext(), and
image_start_ext(). These functions assume linearly mapped flash is
available,
so if you’re using paged flash, you’ll need to modify the routines to page
the flash.



Regards,

Ricardo Kazumi Ashikawa


Hello,

Paged flash is indeed supported by our embedding toolkit. If you have
the
latest Board Support Package (BSP) for x86, it contains source code for
a flash filesystem driver for the AMD SC400 evaluation board. This code
can be used as a starting point for developing your own custom flash
driver.

Within this flash source you will find a file called f3s_sc400_page.c,
which contains the paging routine. This routine is required in all QNX
6
flash drivers, whether the flash is linearly mapped, or paged. It is
here that you would insert the hardware-specific code necessary to hit
the page configuration registers of your hardware.

Developing a flash driver that supports paged flash will allow you to
create and use a QNX 6 flash filesystem on your hardware. However, you
mentioned placing a boot image, created with mkifs, in flash. The
placing
of the image can be done with the flash driver, but if you intend to
boot
that image from an Initial Program Loader (IPL) that you develop
yourself,
paging code will also have to be inserted into the IPL, to allow the
boot
image to be copied from paged flash to DRAM.



\


Dave Green (> dgreen@qnx.com> )

QNX Software Systems Ltd.
http://www.qnx.com

Jeff Maass <jmaass@columbus.rr.com> wrote:

Dave:

This is the x86 Board Support Package (BSP) that costs and additional
$5000+?

Currently, the BSP’s are in beta, and cost nothing besides agreeing to
a beta test Agreement. As for the cost of the product when released,
that’s someone else’s decision. :slight_smile:




Jeff Maass > jmaass@columbus.rr.com > Located near Columbus Ohio
USPSA # L-1192 NROI/CRO Amateur Radio K8ND
Maass’ IPSC Resources Page: > http://home.columbus.rr.com/jmaass



“Dave Green” <> dgreen@qnx.com> > wrote in message
news:9pft18$kvg$> 1@nntp.qnx.com> …
Ricardo Kazumi Ashikawa <> ashikawa@dixtal.com.br> > wrote:
Hi,

Thanks for your response.
Here is what I want to do, and I would like to know if it is possible.
We have a memory mapped flash that works as a extended BIOS, that is, it
has
extended BIOS identifier (0x55aa).
I want it to intercept BIOS call to floppy drive A:, and then copy a
program
from flash to RAM, and finally run this code. This code would copy
compressed image created by mkifs and boot QNX. Is it possible?
Another possibility would be to have a code inside extended BIOS that
would
copy compressed image created by mkifs from flash to RAM and boot. Is it
possible?
How should I do either way? If I just copy from flash to RAM and “jump”
to
the begining of the code on RAM, will it work?

Yes, it’s possible, and the method we use is a combination of the two
possibilities that you mentioned. The x86 BSP that I mentioned earlier
also contains sample source for generating a BIOS extension IPL which
allows the SC400 evaluation board to boot from flash. Very little of the
code is specific to the SC400, and it will work for any BIOS system which
provides a facility for executing a user-generated BIOS extension.
Basically, it goes like this;

  1. Copy the code from
    /usr/src/bsp-6.1.0/x86/sc400/src/hardware/ipl/boards/sc400_ext
    to some other directory, ex.
    /usr/src/bsp-6.1.0/x86/my_bsp/src/hardware/ipl/boards/my_bios_ext

  2. remove the code from main.c which deals with setting up the SC400’s
    flash chip selects; you probably don’t need it on your hardware.

  3. make the binary IPL

  4. Run the mkrom utility on the resultant binary (NOTE: mkrom didn’t get
    shipped with QNX 6.1.0; I’ll put a copy in the R&D developer’s corner
    of qdn.qnx.com - go to > http://qdn.qnx.com> , click on “experimental
    software”, and look for mkrom under “new stuff”). mkrom pads the IPL
    out to a 1K boundary, and then fills in the first 6 bytes of the IPL
    with the 55AA BIOS extension signature, as well as the size and
    checksum bytes, and the proper jump instruction.

ex.
mkrom ipl-my_bios_ext

  1. Place the BIOS extension that you’ve created into your flash, such
    that it will get executed by your BIOS.

Here’s what it does, in general;

-when it gets executed, it re-vectors the BIOS INT19 disk boot call
to INT 0xF8

-copies itself to the area of DRAM just under 1M. For example, if the
size of the BIOS extension was 6k, it will copy itself to address
1042432 (1M - 6k).

-transfers execution from flash/ROM to DRAM

-exits, returning control to the BIOS

Now, when the BIOS has finished the rest of its work, it calls int19
to boot from disk, but your code gets executed instead. When it returns
to the IPL, c main() of the IPL is called, which then calls our IPL
library
functions for booting from flash: image_scan_ext(), image_setup_ext(), and
image_start_ext(). These functions assume linearly mapped flash is
available,
so if you’re using paged flash, you’ll need to modify the routines to page
the flash.



Regards,

Ricardo Kazumi Ashikawa


Hello,

Paged flash is indeed supported by our embedding toolkit. If you have
the
latest Board Support Package (BSP) for x86, it contains source code for
a flash filesystem driver for the AMD SC400 evaluation board. This code
can be used as a starting point for developing your own custom flash
driver.

Within this flash source you will find a file called f3s_sc400_page.c,
which contains the paging routine. This routine is required in all QNX
6
flash drivers, whether the flash is linearly mapped, or paged. It is
here that you would insert the hardware-specific code necessary to hit
the page configuration registers of your hardware.

Developing a flash driver that supports paged flash will allow you to
create and use a QNX 6 flash filesystem on your hardware. However, you
mentioned placing a boot image, created with mkifs, in flash. The
placing
of the image can be done with the flash driver, but if you intend to
boot
that image from an Initial Program Loader (IPL) that you develop
yourself,
paging code will also have to be inserted into the IPL, to allow the
boot
image to be copied from paged flash to DRAM.



\


Dave Green (> dgreen@qnx.com> )

QNX Software Systems Ltd.
http://www.qnx.com
\

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

Hi, Dave!

Again, thanks for your quick response.
Will mkrom generate a image that will work as a extended BIOS? So I will not
have to code extended BIOS, that reads IPL from flash to RAM and run it.
I checked qnx site, but still could not find mkrom. When will it be
available?


Regards,

Ricardo Kazumi Ashikawa


Yes, it’s possible, and the method we use is a combination of the two
possibilities that you mentioned. The x86 BSP that I mentioned earlier
also contains sample source for generating a BIOS extension IPL which
allows the SC400 evaluation board to boot from flash. Very little of the
code is specific to the SC400, and it will work for any BIOS system which
provides a facility for executing a user-generated BIOS extension.
Basically, it goes like this;

  1. Copy the code from
    /usr/src/bsp-6.1.0/x86/sc400/src/hardware/ipl/boards/sc400_ext
    to some other directory, ex.
    /usr/src/bsp-6.1.0/x86/my_bsp/src/hardware/ipl/boards/my_bios_ext

  2. remove the code from main.c which deals with setting up the SC400’s
    flash chip selects; you probably don’t need it on your hardware.

  3. make the binary IPL

  4. Run the mkrom utility on the resultant binary (NOTE: mkrom didn’t get
    shipped with QNX 6.1.0; I’ll put a copy in the R&D developer’s corner
    of qdn.qnx.com - go to > http://qdn.qnx.com> , click on “experimental
    software”, and look for mkrom under “new stuff”). mkrom pads the IPL
    out to a 1K boundary, and then fills in the first 6 bytes of the IPL
    with the 55AA BIOS extension signature, as well as the size and
    checksum bytes, and the proper jump instruction.

ex.
mkrom ipl-my_bios_ext

  1. Place the BIOS extension that you’ve created into your flash, such
    that it will get executed by your BIOS.

Here’s what it does, in general;

-when it gets executed, it re-vectors the BIOS INT19 disk boot call
to INT 0xF8

-copies itself to the area of DRAM just under 1M. For example, if the
size of the BIOS extension was 6k, it will copy itself to address
1042432 (1M - 6k).

-transfers execution from flash/ROM to DRAM

-exits, returning control to the BIOS

Now, when the BIOS has finished the rest of its work, it calls int19
to boot from disk, but your code gets executed instead. When it returns
to the IPL, c main() of the IPL is called, which then calls our IPL
library
functions for booting from flash: image_scan_ext(), image_setup_ext(), and
image_start_ext(). These functions assume linearly mapped flash is
available,
so if you’re using paged flash, you’ll need to modify the routines to page
the flash.

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

Hi, Dave!

Again, thanks for your quick response.
Will mkrom generate a image that will work as a extended BIOS? So I will not
have to code extended BIOS, that reads IPL from flash to RAM and run it.
I checked qnx site, but still could not find mkrom. When will it be
available?

Yes, mkrom converts a binary into a BIOS extension, which will get
executed by any BIOS which is capable of executing user added extensions.
I have passed the utility along to the person who will put it on to the
web site; it should be available some time today.


Regards,

Ricardo Kazumi Ashikawa



Yes, it’s possible, and the method we use is a combination of the two
possibilities that you mentioned. The x86 BSP that I mentioned earlier
also contains sample source for generating a BIOS extension IPL which
allows the SC400 evaluation board to boot from flash. Very little of the
code is specific to the SC400, and it will work for any BIOS system which
provides a facility for executing a user-generated BIOS extension.
Basically, it goes like this;

  1. Copy the code from
    /usr/src/bsp-6.1.0/x86/sc400/src/hardware/ipl/boards/sc400_ext
    to some other directory, ex.
    /usr/src/bsp-6.1.0/x86/my_bsp/src/hardware/ipl/boards/my_bios_ext

  2. remove the code from main.c which deals with setting up the SC400’s
    flash chip selects; you probably don’t need it on your hardware.

  3. make the binary IPL

  4. Run the mkrom utility on the resultant binary (NOTE: mkrom didn’t get
    shipped with QNX 6.1.0; I’ll put a copy in the R&D developer’s corner
    of qdn.qnx.com - go to > http://qdn.qnx.com> , click on “experimental
    software”, and look for mkrom under “new stuff”). mkrom pads the IPL
    out to a 1K boundary, and then fills in the first 6 bytes of the IPL
    with the 55AA BIOS extension signature, as well as the size and
    checksum bytes, and the proper jump instruction.

ex.
mkrom ipl-my_bios_ext

  1. Place the BIOS extension that you’ve created into your flash, such
    that it will get executed by your BIOS.

Here’s what it does, in general;

-when it gets executed, it re-vectors the BIOS INT19 disk boot call
to INT 0xF8

-copies itself to the area of DRAM just under 1M. For example, if the
size of the BIOS extension was 6k, it will copy itself to address
1042432 (1M - 6k).

-transfers execution from flash/ROM to DRAM

-exits, returning control to the BIOS

Now, when the BIOS has finished the rest of its work, it calls int19
to boot from disk, but your code gets executed instead. When it returns
to the IPL, c main() of the IPL is called, which then calls our IPL
library
functions for booting from flash: image_scan_ext(), image_setup_ext(), and
image_start_ext(). These functions assume linearly mapped flash is
available,
so if you’re using paged flash, you’ll need to modify the routines to page
the flash.

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

Hi, Dave!

Again, thanks for your quick response.
Will mkrom generate a image that will work as a extended BIOS? So I will
not
have to code extended BIOS, that reads IPL from flash to RAM and run it.
I checked qnx site, but still could not find mkrom. When will it be
available?

Yes, mkrom converts a binary into a BIOS extension, which will get
executed by any BIOS which is capable of executing user added extensions.
I have passed the utility along to the person who will put it on to the
web site; it should be available some time today.

Great! I have just downloaded mkrom and it works perfectly. Will a DOS
version be released?
Now I have a doubt about flash access. How does IPL know how to access
flash, as it is paged? I will not need a flash filesystem, so I guess I will
not need to code a devf-my-flash, right? So, will I have to change image_*
functions? Or is there a better way around?


Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

Hi, Dave!

Again, thanks for your quick response.
Will mkrom generate a image that will work as a extended BIOS? So I will
not
have to code extended BIOS, that reads IPL from flash to RAM and run it.
I checked qnx site, but still could not find mkrom. When will it be
available?

Yes, mkrom converts a binary into a BIOS extension, which will get
executed by any BIOS which is capable of executing user added extensions.
I have passed the utility along to the person who will put it on to the
web site; it should be available some time today.

Great! I have just downloaded mkrom and it works perfectly. Will a DOS
version be released?
Now I have a doubt about flash access. How does IPL know how to access
flash, as it is paged? I will not need a flash filesystem, so I guess I will
not need to code a devf-my-flash, right? So, will I have to change image_*
functions? Or is there a better way around?

First of all, there won’t be a DOS version released, but there may be a
windows version released at some point in the future, as part of a
Windows-based cross development system. For now, you’ll need to use the
QNX version.

For getting your IPL to the board, I assume you have some sort of
DOS utility which allows you to copy images to the paged flash, and that
this is what you used to copy the IPL BIOS extension to the flash, and perhaps the
boot image you generated with mkifs.

As for booting with the IPL, the routines (image_scan_ext() and image_setup_ext())
expect linear memory, so you’ll need to do some extra work to boot from
paged flash. I’d recommend leaving the IPL routines alone, and writing an
extra routine which copies the boot image from paged flash to DRAM first, and
then calling the normal IPL functions.


Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

First of all, there won’t be a DOS version released, but there may be a
windows version released at some point in the future, as part of a
Windows-based cross development system. For now, you’ll need to use the
QNX version.

Fine! That is exactly what I need! I have QNX SDK for Windows.


For getting your IPL to the board, I assume you have some sort of
DOS utility which allows you to copy images to the paged flash, and that
this is what you used to copy the IPL BIOS extension to the flash, and
perhaps the
boot image you generated with mkifs.

As for booting with the IPL, the routines (image_scan_ext() and
image_setup_ext())
expect linear memory, so you’ll need to do some extra work to boot from
paged flash. I’d recommend leaving the IPL routines alone, and writing an
extra routine which copies the boot image from paged flash to DRAM first,
and
then calling the normal IPL functions.

Alright. So, I just tried to code image_download_my_flash in IPL, but I have
some
doubts.
The c main in ipl runs in real-mode, right? I could not access flash memory.
When I am running a program in protected mode, I just run mmap to 0xD8000
and it works fine. However, when I tried to access 0xD8000 in
image_download_my_flash, I could not access flash memory correctly. It
always returns 00 for all data. Is this approach correct? If not so, which
address should be the correct one?


This piece of code works after QNX boot:

int main( void )
{
unsigned char *addr, *buff;
int i;
_uintptr map;

ThreadCtl( _NTO_TCTL_IO, 0 );
map = mmap_device_io( 1, (_uint64) 0x20C ); // paging address
out8( map, 0 );
addr = (unsigned char *) mmap( 0, 0x2000, PROT_READ, MAP_SHARED | MAP_PHYS,
NOFD, 0xD8000 );
assert( addr != MAP_FAILED );
buff = addr;
for( i = 0; i < 256; i++, buff++ )
printf( “[%02x]”, *buff );
return 0;
}

But this ipl code does not work…

int image_download_my_flash( unsigned dst_address )
{
unsigned char *src, *dst, i;
unsigned j;

(int)dst = dst_address;

for( i = 1; i < 128; i++ ) // read 127 pages starting from 1
{
out8( 0x20c, i );
for( j = 0, (int)src = 0xD8000; j < 0x8000; j++, dst++, src++ )
*dst = *src;
}
return 0;
}


Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

First of all, there won’t be a DOS version released, but there may be a
windows version released at some point in the future, as part of a
Windows-based cross development system. For now, you’ll need to use the
QNX version.

Fine! That is exactly what I need! I have QNX SDK for Windows.



For getting your IPL to the board, I assume you have some sort of
DOS utility which allows you to copy images to the paged flash, and that
this is what you used to copy the IPL BIOS extension to the flash, and
perhaps the
boot image you generated with mkifs.

As for booting with the IPL, the routines (image_scan_ext() and
image_setup_ext())
expect linear memory, so you’ll need to do some extra work to boot from
paged flash. I’d recommend leaving the IPL routines alone, and writing an
extra routine which copies the boot image from paged flash to DRAM first,
and
then calling the normal IPL functions.

Alright. So, I just tried to code image_download_my_flash in IPL, but I have
some
doubts.
The c main in ipl runs in real-mode, right? I could not access flash memory.
When I am running a program in protected mode, I just run mmap to 0xD8000
and it works fine. However, when I tried to access 0xD8000 in
image_download_my_flash, I could not access flash memory correctly. It
always returns 00 for all data. Is this approach correct? If not so, which
address should be the correct one?

Correct, we’re still running in real mode here. This means that you don’t
need to use threadctl or mmap calls to map memory and I/O - the kernel
hasn’t loaded yet, and you can still talk directly to the hardware. It
also means that you have to convert physical addresses to segment:offset
addresses to access memory. The following code may help. It was written
a couple of assembler versions ago, so the inline asm isn’t guaranteed
to still work, but it should be a start:


asm(".code16gcc");

#include “ipl.h”
#include <x86/inout.h>

int main(){
unsigned long image = 0;

print_string(“QNX 6 paged flash loader\n”);
print_string(“press any key to boot from disk\n”);

if (get_timed_char (2000) != -1) {
print_string (“stopped\n”);
return 0;
}

// copy the first 512k of flash (32 pages * 16k per page) to DRAM (offset 64k)
print_string(“copying pages of flash to DRAM…\n”);
copy_pages(0x10000,0,0x20);

print_string(“done. Scanning for image in DRAM…\n”);

// the image sits at 0x10000, and the IPL, which was
// at the beginning of the flash, occupies the first 8k
image = image_scan_ext(0x12000, 0x12800);

if(image == 0xffffffff)
{
print_string(“image_scan: no image found\n”);
return(0);
}
print_sl("image scan found image at: ", image);

if (image_setup_ext(image) !=0){
print_string(“image_setup failed\n”);
return(0);
}

image_start_ext();

return(0);
}

//copy_pages.c
asm(".code16gcc");

#include “ipl.h”
#include <string.h>
#include <x86/inout.h>

void my_copy(unsigned long dst, unsigned long src, unsigned long size)

/*
This function converts the src address to a segment and offset,
gets a dword of data, converts the destination address to a
segment and offset, and writes the data there.
*/

{
unsigned long src_seg;
unsigned long src_off;
unsigned long dst_seg;
unsigned long dst_off;
unsigned long data;

unsigned long tmp = 0;


while(size > 0)
{
// get the data from the src address
src_seg = (src >> 4) & ~0xfff;
src_off = src & 0xffff;

asm volatile(
“pushw %%es\n\t”
“movw %1,%%ax\n\t”
“movw %%ax,%%es\n\t”
“movl %%es:(%2), %%eax\n\t”
“popw %%es\n\t”
:"=a" (data)
:“m” (src_seg), “r”(src_off)
:“memory”
);

// figure out the destination seg and offset, and copy the data there
dst_seg = (dst >> 4) & ~0xfff;
dst_off = dst & 0xffff;

asm volatile(
“pushw %%es\n\t”
“movw %0,%%ax\n\t”
“movw %%ax,%%es\n\t”
“movl %1,%%eax\n\t”
“movl %%eax,%%es:(%2)\n\t”
“popw %%es\n\t”
:
:“m” (dst_seg), “r” (data), “r” (dst_off)
:“eax”,“memory”
);
dst += 4;
src += 4;
size -= 4;
}
}

void copy_pages(unsigned long dest, int start_page, int end_page)

/*
Copy the specified number of flash pages to DRAM
*/
{
int i;

for(i = start_page; i < end_page; i++)
{
// set up the proper page
out8(0x20c, i & 0xff);

// each page is 16k (0x4000), and the flash window sits at 0xD8000
my_copy(dest,0xd8000,0x4000);
dest += 0x4000;
}
}

If you have trouble with the code in the my_copy() function, you might try
using the int15_copy() function instead, which is part of the IPL library. It uses
the BIOS int15 function 87 call to copy a block of memory from an address above
1M when in real mode. It’s normally called in image_scan_ext() and image_setup_ext()
when booting from linear flash which is mapped above 1M, but it should work
when both the source and destination addresses are below 1M, as is the case here.
The prototype is:

unsigned char int15_copy(long from, long to, long len);


Hope this helps,

Dave


This piece of code works after QNX boot:

int main( void )
{
unsigned char *addr, *buff;
int i;
_uintptr map;

ThreadCtl( _NTO_TCTL_IO, 0 );
map = mmap_device_io( 1, (_uint64) 0x20C ); // paging address
out8( map, 0 );
addr = (unsigned char *) mmap( 0, 0x2000, PROT_READ, MAP_SHARED | MAP_PHYS,
NOFD, 0xD8000 );
assert( addr != MAP_FAILED );
buff = addr;
for( i = 0; i < 256; i++, buff++ )
printf( “[%02x]”, *buff );
return 0;
}

But this ipl code does not work…

int image_download_my_flash( unsigned dst_address )
{
unsigned char *src, *dst, i;
unsigned j;

(int)dst = dst_address;

for( i = 1; i < 128; i++ ) // read 127 pages starting from 1
{
out8( 0x20c, i );
for( j = 0, (int)src = 0xD8000; j < 0x8000; j++, dst++, src++ )
*dst = *src;
}
return 0;
}



Regards,

Ricardo Kazumi Ashikawa

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

The c main in ipl runs in real-mode, right? I could not access flash
memory.
When I am running a program in protected mode, I just run mmap to
0xD8000
and it works fine. However, when I tried to access 0xD8000 in
image_download_my_flash, I could not access flash memory correctly. It
always returns 00 for all data. Is this approach correct? If not so,
which
address should be the correct one?

Correct, we’re still running in real mode here. This means that you don’t
need to use threadctl or mmap calls to map memory and I/O - the kernel
hasn’t loaded yet, and you can still talk directly to the hardware. It
also means that you have to convert physical addresses to segment:offset
addresses to access memory. The following code may help. It was written
a couple of assembler versions ago, so the inline asm isn’t guaranteed
to still work, but it should be a start:

Thanks a lot! Now I could read paged-flash!
However, as this code is running on 16-bit real mode, how will I be able to
copy a 2 Mb-sized image from flash to DRAM? Is it possible to change to
protected mode, mmap both DRAM and flash, copy from flash to DRAM and then
run image_setup_ext? If so, how?


If you have trouble with the code in the my_copy() function, you might try
using the int15_copy() function instead, which is part of the IPL library.
It uses
the BIOS int15 function 87 call to copy a block of memory from an address
above
1M when in real mode. It’s normally called in image_scan_ext() and
image_setup_ext()
when booting from linear flash which is mapped above 1M, but it should
work
when both the source and destination addresses are below 1M, as is the
case here.
The prototype is:

unsigned char int15_copy(long from, long to, long len);

I could not use int15_copy… I tried some combinations but it always
returns code 2…

int15_copy( 0xD8000000, 0x00100000, 0x8000 )
int15_copy( 0x000D8000, 0x00100000, 0x8000 )

Both ways above returned code 2…


Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

The c main in ipl runs in real-mode, right? I could not access flash
memory.
When I am running a program in protected mode, I just run mmap to
0xD8000
and it works fine. However, when I tried to access 0xD8000 in
image_download_my_flash, I could not access flash memory correctly. It
always returns 00 for all data. Is this approach correct? If not so,
which
address should be the correct one?

Correct, we’re still running in real mode here. This means that you don’t
need to use threadctl or mmap calls to map memory and I/O - the kernel
hasn’t loaded yet, and you can still talk directly to the hardware. It
also means that you have to convert physical addresses to segment:offset
addresses to access memory. The following code may help. It was written
a couple of assembler versions ago, so the inline asm isn’t guaranteed
to still work, but it should be a start:

Thanks a lot! Now I could read paged-flash!
However, as this code is running on 16-bit real mode, how will I be able to
copy a 2 Mb-sized image from flash to DRAM? Is it possible to change to
protected mode, mmap both DRAM and flash, copy from flash to DRAM and then
run image_setup_ext? If so, how?

It’s possible, but I don’t have any code sample describing how to do it…
you would need to call the protected_mode function, but you also need to have
things set up properly before doing so. Take a look at the SC400 non-BIOS
IPL code, particularly _start.S, to see how things are set up for a jump to
protected mode. Normally, with non-BIOS IPL, we switch to protected mode
as soon as possible, so that flash in upper memory can be accessed. When
using a BIOS extension, we rely on the int15 copy to access flash in high
memory, but the boot image is kept small, and copied to low memory. After
control is transferred to startup, startup takes care of the switch to
protected mode. Take a look at:
/usr/src/bsp-6.1.0/x86/bios/src/hardware/startup/bootfile/x86-o/bios.s
to see how the switch to protected mode is done.



If you have trouble with the code in the my_copy() function, you might try
using the int15_copy() function instead, which is part of the IPL library.
It uses
the BIOS int15 function 87 call to copy a block of memory from an address
above
1M when in real mode. It’s normally called in image_scan_ext() and
image_setup_ext()
when booting from linear flash which is mapped above 1M, but it should
work
when both the source and destination addresses are below 1M, as is the
case here.
The prototype is:

unsigned char int15_copy(long from, long to, long len);

I could not use int15_copy… I tried some combinations but it always
returns code 2…

int15_copy( 0xD8000000, 0x00100000, 0x8000 )
int15_copy( 0x000D8000, 0x00100000, 0x8000 )

Both ways above returned code 2…

According to some docs I found on the web for this function call, error 2
is an interrupt error. I’m not sure what this might indicate, but it could
mean that this function is not supported by your BIOS.


Regards,

Ricardo Kazumi Ashikawa

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

However, as this code is running on 16-bit real mode, how will I be able
to
copy a 2 Mb-sized image from flash to DRAM? Is it possible to change to
protected mode, mmap both DRAM and flash, copy from flash to DRAM and
then
run image_setup_ext? If so, how?

It’s possible, but I don’t have any code sample describing how to do it…
you would need to call the protected_mode function, but you also need to
have
things set up properly before doing so. Take a look at the SC400 non-BIOS
IPL code, particularly _start.S, to see how things are set up for a jump
to
protected mode. Normally, with non-BIOS IPL, we switch to protected mode
as soon as possible, so that flash in upper memory can be accessed. When
using a BIOS extension, we rely on the int15 copy to access flash in high
memory, but the boot image is kept small, and copied to low memory. After
control is transferred to startup, startup takes care of the switch to
protected mode. Take a look at:
/usr/src/bsp-6.1.0/x86/bios/src/hardware/startup/bootfile/x86-o/bios.s
to see how the switch to protected mode is done.

Well… Is it possible to switch to protected mode through inline assembly?
For example:
void enter_protected_mode()
{
static char gdt[16];
unsigned long gdt_seg;
unsigned long gdt_off;

gdt_seg = ( (unsigned long) gdt >> 4 ) & ~0xfff;
gdt_off = (unsigned long) gdt & 0xffff;

asm volatile(
“pushw %%ds\n\t”
“pushw %%ax\n\t”
“movw %0,%%ax\n\t”
“movw %%ax,%%ds\n\t”
“movw %1,%%ax\n\t”
“call protected_mode\n\t”
“popw %%ax\n\t”
“popw %%ds\n\t”
:
:“m” (gdt_seg), “m” (gdt_off)
:“memory”
);
}

And I just cannot use mmap since I cannot link ipl if I use mmap. Even if I
use -lc to link ipl, it keeps asking for mmap. Where is it?



Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

However, as this code is running on 16-bit real mode, how will I be able
to
copy a 2 Mb-sized image from flash to DRAM? Is it possible to change to
protected mode, mmap both DRAM and flash, copy from flash to DRAM and
then
run image_setup_ext? If so, how?

It’s possible, but I don’t have any code sample describing how to do it…
you would need to call the protected_mode function, but you also need to
have
things set up properly before doing so. Take a look at the SC400 non-BIOS
IPL code, particularly _start.S, to see how things are set up for a jump
to
protected mode. Normally, with non-BIOS IPL, we switch to protected mode
as soon as possible, so that flash in upper memory can be accessed. When
using a BIOS extension, we rely on the int15 copy to access flash in high
memory, but the boot image is kept small, and copied to low memory. After
control is transferred to startup, startup takes care of the switch to
protected mode. Take a look at:
/usr/src/bsp-6.1.0/x86/bios/src/hardware/startup/bootfile/x86-o/bios.s
to see how the switch to protected mode is done.

An update to what I said this morning… another developer had previously
modified the image_setup_ext() and image_start_ext() functions to allow
BIOS extension IPL code to boot an image targetted at > 1M in DRAM, thereby
enabling booting of images larger than 640k from BIOS extension IPL. These
changes aren’t yet incorporated into libipl.a, but I’ve built a new libipl.a
for x86 which contains these changes (along with a fix for int15_copy()),
and requested that it be placed in the experimental software/fixes section
of the R&D developer’s corner.

However, this still doesn’t solve your original problem of how to put the
image from paged flash into linear memory. I’d suggest that you do the
following:

  1. Make a small (<640k) boot image, and place it in flash.

  2. Generate a new BIOS extension IPL, using the updated libipl.a, and
    verify that you can boot the small image, by first copying it from paged
    flash to low DRAM, and then calling the image_*_ext() functions to
    load the image.

  3. Once you can boot into Neutrino, replace the inline asm code that
    you used to copy the image from paged flash to low DRAM, with the
    int15_copy() function (there was a bug fix which didn’t make it
    into the released lib, which may have caused your earlier problem
    with int15_copy()).

  4. If int15_copy() works, it should be possible to use it to copy
    pages of flash to DRAM above 1M, thereby allowing you to load
    your 2M image, without having to switch into protected mode using
    inline assembly.

Well… Is it possible to switch to protected mode through inline assembly?
For example:
void enter_protected_mode()
{
static char gdt[16];
unsigned long gdt_seg;
unsigned long gdt_off;

gdt_seg = ( (unsigned long) gdt >> 4 ) & ~0xfff;
gdt_off = (unsigned long) gdt & 0xffff;

asm volatile(
“pushw %%ds\n\t”
“pushw %%ax\n\t”
“movw %0,%%ax\n\t”
“movw %%ax,%%ds\n\t”
“movw %1,%%ax\n\t”
“call protected_mode\n\t”
“popw %%ax\n\t”
“popw %%ds\n\t”
:
:“m” (gdt_seg), “m” (gdt_off)
:“memory”
);
}

And I just cannot use mmap since I cannot link ipl if I use mmap. Even if I
use -lc to link ipl, it keeps asking for mmap. Where is it?

mmap() is a C library function which is not available until after the OS has
loaded.


Regards,

Ricardo Kazumi Ashikawa

Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com

An update to what I said this morning… another developer had previously
modified the image_setup_ext() and image_start_ext() functions to allow
BIOS extension IPL code to boot an image targetted at > 1M in DRAM,
thereby
enabling booting of images larger than 640k from BIOS extension IPL. These
changes aren’t yet incorporated into libipl.a, but I’ve built a new
libipl.a
for x86 which contains these changes (along with a fix for int15_copy()),
and requested that it be placed in the experimental software/fixes section
of the R&D developer’s corner.

Well… So there was a bug on int15_copy, right? I could not understand why
it did not work and I could not find any documentation for int15 87h for
32-bit address copy…
As I purchased Embedding SDK, will I receive corrected codes as soon as they
are ready?


However, this still doesn’t solve your original problem of how to put the
image from paged flash into linear memory. I’d suggest that you do the
following:

  1. Make a small (<640k) boot image, and place it in flash.

  2. Generate a new BIOS extension IPL, using the updated libipl.a, and
    verify that you can boot the small image, by first copying it from
    paged
    flash to low DRAM, and then calling the image_*_ext() functions to
    load the image.

  3. Once you can boot into Neutrino, replace the inline asm code that
    you used to copy the image from paged flash to low DRAM, with the
    int15_copy() function (there was a bug fix which didn’t make it
    into the released lib, which may have caused your earlier problem
    with int15_copy()).

  4. If int15_copy() works, it should be possible to use it to copy
    pages of flash to DRAM above 1M, thereby allowing you to load
    your 2M image, without having to switch into protected mode using
    inline assembly.

Ok! I will try as soon as I put my hands on new version of libipl.a!
Well… It is not online yet…


Regards,

Ricardo Kazumi Ashikawa

Ricardo Kazumi Ashikawa <ashikawa@dixtal.com.br> wrote:

An update to what I said this morning… another developer had previously
modified the image_setup_ext() and image_start_ext() functions to allow
BIOS extension IPL code to boot an image targetted at > 1M in DRAM,
thereby
enabling booting of images larger than 640k from BIOS extension IPL. These
changes aren’t yet incorporated into libipl.a, but I’ve built a new
libipl.a
for x86 which contains these changes (along with a fix for int15_copy()),
and requested that it be placed in the experimental software/fixes section
of the R&D developer’s corner.

Well… So there was a bug on int15_copy, right? I could not understand why
it did not work and I could not find any documentation for int15 87h for
32-bit address copy…
As I purchased Embedding SDK, will I receive corrected codes as soon as they
are ready?

Answered via e-mail.


However, this still doesn’t solve your original problem of how to put the
image from paged flash into linear memory. I’d suggest that you do the
following:

  1. Make a small (<640k) boot image, and place it in flash.

  2. Generate a new BIOS extension IPL, using the updated libipl.a, and
    verify that you can boot the small image, by first copying it from
    paged
    flash to low DRAM, and then calling the image_*_ext() functions to
    load the image.

  3. Once you can boot into Neutrino, replace the inline asm code that
    you used to copy the image from paged flash to low DRAM, with the
    int15_copy() function (there was a bug fix which didn’t make it
    into the released lib, which may have caused your earlier problem
    with int15_copy()).

  4. If int15_copy() works, it should be possible to use it to copy
    pages of flash to DRAM above 1M, thereby allowing you to load
    your 2M image, without having to switch into protected mode using
    inline assembly.

Ok! I will try as soon as I put my hands on new version of libipl.a!
Well… It is not online yet…



Regards,

Ricardo Kazumi Ashikawa



Dave Green (dgreen@qnx.com)

QNX Software Systems Ltd.
http://www.qnx.com