User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: Baking Pi

Thu Sep 20, 2012 7:51 pm

Have tried the latest boot loaders ?
https://github.com/raspberrypi/firmware ... aster/boot
Batteries not included, Some assembly required.

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Thu Sep 20, 2012 8:01 pm

Thanks for the response DexOS - I took a very quick look at your projects and will definitely go back for another look when I find more time, they look like fun.

First of all your suggested code change worked, I made the change and then reverted the config.txt file back to the default, so thank-you very much for both the response and a solution.

But I am not convinced that the problem is because either of the addresses are relative or absolute addresses. They both look absolute to me and they are the same absolute addresses for all of the lessons ok1 through to ok5.

ok5 is the only one I believe that does not work. What's different - we the author answers this indirectly in ok2, the code is growing between each lesson and is quite a bit larger in ok5.

I did a lot of debugging before finding the solution to the problem (kernel_old=1) as suggested in this post.

I first of all thought the problem was with my addition, I wrote some code that seemed to load the start of the data but not anything further on. So I could tell most of the code was working and it seemed that part of the data was being overwritten. I was thinking along the lines of the data being too big to fit in a single register or the double ldr command which was not explained as when I commented out the second command more of the code seemed to work. Still a beginner as you can tell...

Code: Select all

	
	ldr ptrn,=pattern
	ldr ptrn,[ptrn]
I have also read (in the links you provided earlier) that the latest release of the raspberry pi os included a new bootloader and so your explanation regarding new bootloaders seems to make sense in this context especially if they are sharing addresses around this area.

So your suggested code basically moves the ok5 code in to 0x80080 which I guess is another absolute location a little bit further on which no longer conflicts with the new bootloader. This leaves a few more questions for me which I will try and dig out for myself as well.
  • What is a reasonable address to start at - is 8080 a 'recommended' location for an os
  • Do I need to move the init section from 0x0000 - I suspect not and its an easy test for me to do now
Thanks again for the response :D

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Thu Sep 20, 2012 9:09 pm

Here is some bed time reading regarding linker scripts http://www.gnuarm.com/pdf/ld.pdf
Chapters 3.1 -> 3.3 provide the answers about the SECTIONS format

But in answer to my 2nd question
Do I need to move the init section from 0x0000
The answer is yes the code no longer worked unless I started the init section at 0x8000 - which means of course the addresses seem to be relative

More questions... what happens if I make all the addresses relative after the init section starting from 0x80000 like this:

Code: Select all

/******************************************************************************
*	kernel.ld
*	 by Alex Chadwick
*
*	A linker script for generation of raspberry pi kernel images.
******************************************************************************/

SECTIONS {
	/*
	* First and formost we need the .init section, containing the IVT.
	*/
	.init 0x8000 : {
		*(.init)
	}
	
	/* 
	* We allow room for the ATAGs and the stack and then start our code at
	* 0x8080.
	*/
	.text : {
		*(.text)
	}
	
	/* 
	* Next we put the data.
	*/
	.data : {
		*(.data)
	}

	/*
	* Finally comes everything else. A fun trick here is to put all other 
	* sections into this section, which will be discarded by default.
	*/
	/DISCARD/ : {
		*(*)
	}
}
Well the answer to that is it also works fine I get my S.O.S flashing LED :o

So what do I take away from this....

Well I might have answered my first question indirectly but still not conclusively
What is a reasonable address to start at - is 8080 a 'recommended' location for an os
I now think the correct address is potentially still 0x8000 - I have read this is where Linux starts for example. I think that perhaps ok1-ok4 were small enough to fit at 0x00000 and ok5 was the 1st instance where it was simply too big.
  • I can't tell the difference between absolute and relative
  • or perhaps nether can my version ld
  • Possibly need to revisit the assembler I am using the YAGARTO toolchain with arm-none-eabi
Anyways need to stop now and start again another time - thanks again for your pointers you have obviously been doing this for a while on many different archetectures DexOS

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Baking Pi

Fri Sep 21, 2012 7:15 am

Here it is in plain(ish) english.

The ARM vector table always starts at 0x0 and carries on for 32 bytes (8 entries of 4 bytes each). The most important entry in this is the reset vector, the first entry - this is where the program counter is on startup.

Early versions of the firmware, and later versions with the kernel_old parameter set in config.txt, load your kernel starting at 0x0 - thus execution will start with the first word of your program (which is usually a vector entry, but could actually be the first instruction of your program if you don't need a vector table). Newer firmware loads the kernel at 0x8000 and places an implicit b 0x8000 at 0x0 that transfers execution to the loaded kernel.

If you need the vector table (for example, if you're handling interrupts), you will need to back-patch it in your code if you're using newer firmware.

After loading the kernel, and before starting execution, the firmware also sets up the atags and command line structures. These are (for the moment, but not required to be) placed at 0x100 - 0x3fff, so if you are using older firmware or kernel_old, you need to leave a 'hole' in your code, lest it gets blown away by the atags stuff. The proper way of locating the atags is by referring to the contents of (from memory) r2 on startup rather than hardcoding 0x100 into your kernel.

0X4000-0x7fff is used (by linux) for the initial mmu pge translation table. You can do what you like with this space in your code, but using it to set up a 1:1 mapping for the mmu is a good idea if you ever want to use dma...

So far, so good.

The difficulty comes from linking with the 'wrong' start address. If you're linking at 0x0, but your code is loaded at 0x8000, or vice versa, all will be well until you hit the first absolute, non-peripheral reference or linker-defined address, in which case you'll be off by 0x8000 one way or another.

The next wrinkle comes from the fact that the atags / arm boot spec does not /require/ the kernel to be loaded at 0x8000. It could, in fact, be loaded anywhere, and if the linux convention changes, the firmware probably will as well - you can't even rely on 0x8000. This means that your code /must/ be position independent if you want it to work with future firmware - you either use /only/ pc-relative addressing, or perform a "cleanup" of absolute addresses in your code after loading.

If you want to write code that will work with /any/ existing firmware, you'll need to :
- start with a valid vector table using pc-relative offsets
- leave a (32768 - 64) byte hole in your code after the vector table.
- back patch the actual vector table at 0x0 with a valid vector table using fixed-up absolute addresses
- write postion independent code or fix up absolute references

Simon.

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Fri Sep 21, 2012 7:55 am

Thanks Simon - I suspected I didn't want to know the answer now I know. Loads more questions for me to knock about with. Your answer is very helpful in clearing up what is going on and for highlighting a solid solution going forward even though I don't fully understand it yet. :D

Focusing narrowly on the contents of the course and getting it to work - I am not sure if anyone else doing the Baking PI course has answered the following questions so I will record them here for now - I will also try to answer them in due course.
  • Does the sample ld script I posted above work for all lessons on the course?
  • Does the sample ld script I posted above work for both versions of the firmware?
  • Why are the absolute memory addresses ignored in the script - I think based on Simon's response above I could use any address as long as its not used by anything else and as such I still expect sticking the .init section at 0x0000 and branching to .main in this case at 0x8000 should work if the ld script was doing what I intended.
This is the crux of the problem at hand in my rather uneducated opinion - I still don't understand why ok1 - ok4 work fine but ok5 breaks - they all use the same ld script - the loading at 0x0000 must be working as the author originally intended with both the old and the new firmware - I still suspect the jump to 0x8000 is the problem...

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Fri Sep 21, 2012 8:02 am

I should add...

As far as I can tell the only code at 0x0000 in this kernel is a .globl _start declaration and branch to the .main section supposedly at 0x8000 according to the ld script.

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Fri Sep 21, 2012 8:12 am

I only have time to answer one of those questions at the moment as it's my wife's birthday and I will otherwise be in the dog box...
Does the sample ld script I posted above work for both versions of the firmware?
No it does not - if I have kernel_old=1 in config.txt with the .init section address starting at 0x8000 and using contiguous address for each subsequent section the kernel fails to start/load correctly

Simply replacing config.txt with the original version makes the code work.

kernel_old=1 must there for have code at 0x0000 for it to work
the new firmware seems to work with code starting at either address but only in some situations

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Baking Pi

Fri Sep 21, 2012 11:26 am

stevendodd wrote:I only have time to answer one of those questions at the moment as it's my wife's birthday and I will otherwise be in the dog box...
Does the sample ld script I posted above work for both versions of the firmware?
No it does not - if I have kernel_old=1 in config.txt with the .init section address starting at 0x8000 and using contiguous address for each subsequent section the kernel fails to start/load correctly
kernel_old, or an old firmware, will load your code starting at 0x0, regardless of what the linker thinks. It will than slap the atags and kernel command line over the top of that, starting at 0x100.

What this means is:

1 - To avoid having your code overwritten by atags and command line, your code must either fit entirely within 0xff bytes, or have a "hole" starting at 0x100 through at least 0x3fff and potentially as far as 0x7fff.
2 - You need to be careful what you're putting in your initial vector table.

The approach I take is to use indirect jumps in the vector table, and let the linker fill in the spaces. This works, and makes vector table patching easier, but your linker script absolutely must be using the same base address as the kernel loader.

Code: Select all

__reset: ldr pc, reset_handler_address
...
.global reset_handler_address
reset_handler_address: .word _reset
this assembles to

Code: Select all

   0:	e59ff018 	ldr	pc, [pc, #24]	; 20 <reset_handler_address>
....
00000020 <reset_handler_address>:
  20:	00000000 	.word	0x00000000
And then, during linkage, the linker shoves the final address of _reset into reset_handler_address.

So, if the linker is using the right base address (0x0 for kernel_old, 0x8000 for newer bootloaders), this will work.

The next option is to make sure that any reset handlers you are going to use can be encoded as a pc-relative offset using 12-bit ARM constant encoding, and then using

Code: Select all

ldr pc, _reset
Because of the way that ldr is encoded, this means that they must be within 0x3fc of the current PC, which basically means that they must be placed between 0x20 and 0xff. That's not a lot of space, and basically doesn't work in the totally naive implementation.

Next up, using direct branches.

Code: Select all

b _reset
This gives you 24 bits of addressing to use, but again, you need to be careful that your linker is using the same base address as the bootloader as the addresses used are absolute. It's a bitch to patch, though, which is why I use the first option.
stevendodd wrote:the new firmware seems to work with code starting at either address but only in some situations
With the new firmware and no kernel_old, your code will be loaded at 0x8000, no matter what you've specified for the starting address in the linker. So, even if you have some random start address defined for the linker, as long as your first instruction is a relative jump, and your code contains no absolute addresses that reference your code or data, it will work.

In order to make everything work easily, you must have the correct base address specified for the linker relative to the bootloader you're going to use. New firmware - 0x8000, old firmware - 0x0 and a hole in your code.

In most cases, you'll want to stop reading at this point. Make sure you're using the right address in linkage, and you're good to go.

Still reading? Stop now.

No?

*** HERE BE DRAGONS ***

There is, in fact, a way to make code that works at *any* link address, but it's pretty hairy to do. In order to do this, we need, at runtime,

- The start address that the linker is using
- The actual start address
- A bit of math to clean everything up
- A certain amount of bloody-mindedness.

Ignoring the first issue, let's look at the second. Remember that when we trigger the reset line, the PC will be set to 0x0. Our code will either be here, or will be accessed indirectly after an implicit jump placed at 0x0 by the bootloader. So the *actual* address of our first instruction will always be in the PC when we are executing the first instruction in our code (hardly a surprise, but it needs stating). In fact, during execution of the first instruction, the PC will be read as (start address + 8). So, if we forget all about exception vector tables (and we can, because everything is "turned off" at boot), we can use the following instructions at the very start to get the actual start address:

Code: Select all

__start:
    mov r3, pc
    sub r3, r3, #8
Next up, we need the start address as far as the linker is concerned. That's pretty easy, we have a handy label __start defined in the last snippet, and that's known to the linker - If we can get that address, we can store it somewhere and use it:

Code: Select all

    ldr r4, __start_address
...
__start_address: .word __start
__start_address will be filled in by the linker, and so we get our start address as far as linkage is concerned. The next step is to calculate an offset to be added to all absolute addresses.

Code: Select all

    sub r3, r3, r4
Now, that's gonna be needed elsewhere for address fixup purposes - we need to store it somewhere that *all* code can get to it. That needs to be a place in memory where nobody is ever going, and which is absolute and known to everyone. Let's use 0xfc (just before the atags table at 0x100)

Code: Select all

    ldr r4, __fixup_address
    str r3, [r4]
...
__fixup_address: .word 0x000000fc
Now let's put in place our actual vector table, which points to our "real" startup code. To make it easy to fix up, we'll be using the indirect jump approach

Code: Select all

    ldr r4, __vector_table_address
    mov r5, #0x00000000
    /* Move the jump instructions */
    ldmia r4!, {r6-r12, r14}
    stmia r5!, {r6-r12, r14}
    /* load the jump table */
    ldmia r4, {r6-r12, r14}
    /* fixup addresses */
    add r6, r6, r3
    add r7, r7, r3
    add r8, r8, r3
    add r9, r9, r3
    add r10, r10, r3
    add r11, r11, r3
    add r12, r12, r3
    add r14, r14, r3
    /* store it */
    stmia r5, {r6-r12, r14}
All of which now leaves us with the simple case of re-jumping to 0x00, which should now be an indirect jump to our actual startup code, and everything should work. The final code is thus:

Code: Select all

__start:
    mov r3, pc
    sub r3, r3, #8
    ldr r4, __start_address
    sub r3, r3, r4
    ldr r4, __fixup_address
    str r3, [r4]
    ldr r4, __vector_table_address
    mov r5, #0x00000000
    /* Move the jump instructions */
    ldmia r4!, {r6-r12, r14}
    stmia r5!, {r6-r12, r14}
    /* load the jump table */
    ldmia r4, {r6-r12, r14}
    /* fixup addresses */
    add r6, r6, r3
    add r7, r7, r3
    add r8, r8, r3
    add r9, r9, r3
    add r10, r10, r3
    add r11, r11, r3
    add r12, r12, r3
    add r14, r14, r3
    /* store it */
    stmia r5, {r6-r12, r14}
    /* and re-reset */
    mov pc, #0x0

__fixup_address: .word 0x000000fc
__start_address: .word __start
__vector_table_address: .word __reset
This fits neatly into the 0xff bytes we have to play with in the case where we're loaded at 0x0. Elsewhere in the code our reset table looks like this:

Code: Select all

__reset:
    ldr pc, reset_handler_address
    ldr pc, undef_handler_address
    ldr pc, svc_handler_address
    ldr pc, prefetch_abort_handler_address
    ldr pc, data_abort_handler_address
_eeagh:    b .
    ldr pc, irq_handler_address
    ldr pc, fiq_handler_address

reset_handler_address: .word _reset_handler
undef_handler_address: .word _undef_handler
svc_handler_address: .word _svc_handler
prefetch_abort_handler_address: .word _prefetch_abort_handler
data_abort_handler_address: .word _data_abort_handler
unused: .word _eeagh
irq_handler_address: .word _irq_handler
fiq_handler_address: .word _fiq_handler

.global reset_handler_address
.global undef_handler_address
.global svc_handler_address
.global prefetch_abort_handler_address
.global data_abort_handler_address
.global irq_handler_address
.global fiq_handler_address

.weak _undef_handler
.set _undef_handler, _eeagh
.weak _svc_handler
.set _svc_handler, _eeagh
.weak _prefetch_abort_handler
.set _prefetch_abort_handler, _eeagh
.weak _data_abort_handler
.set _data_abort_handler, _eeagh
.weak _irq_handler
.set _irq_handler, _eeagh
.weak _fiq_handler
.set _fiq_handler, _eeagh
The only entry point we *need* to define in code is then _reset_handler, which is our main entry point. The rest are weak symbols which we can either define or not; in the case where we don't define them, they will be redirected to the unused vector, which goes into a tight loop.

The only other thing that remains to be noted is that the code above doesn't touch r0, r1 or r2, which have defined values set up the boot loader. So when we finally make it into _reset_handler, r0, r1 and r2 are set up as expected, we have a valid (and easily patchable) vector table at 0x0, and we have the fixup offset defined at 0xfc, ready to be used elsewhere.

If we're doing this, we can then link with the assumption that we're at zero, leave a hole in the code until a (linker-relative) 0x8000, and we're good to go.

Like I said. It's a bit gnarly. Or, for the few (probably 0% or readers) who will get it,
Eeagh! Iron Bird!
Simon

User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: Baking Pi

Fri Sep 21, 2012 12:27 pm

tufty can explain thing's much better than me, and i have been coding OS's for a number of years, but only since May on a ARM processors.
Also i have not study those tut that much and use fasmarm for my arm assembly.
Having said that, here some pointers.
The tut5 is the first tut to use data
tut5:
So far, all we've had to do with our operating system is provide instructions to be followed. Sometimes however, instructions are only half the story. Our operating systems may need data.
This is why there is a problem with tut5 and the one's before are OK.
The data address at a guess would be 0x8000 + text size
Now the kernel.img is 32k of zero's plus the size of the text plus size of data.
;**********
;init = 0x8000
;**********
;text = ?
;**********
;data =?
So the address of data is 0x8000 plus size of text size
Now this is fine if loaded to zero, but if loaded to 0x8000 then the data is at real address is 0x8000 plus 0x8000 plus text.
So when it try to loaded it from "0x8000 plus size of text" it will most likely find a lot of zeros.

You can try this by adding 0x8000 to the reg that holds the data's address.

My kernel is loaded to 0x8000 eg:

Code: Select all

format binary as 'img'
org	0x8000
use32
; -------------------------------------------------------
; Start
; -------------------------------------------------------
Start:
       b     main_start
I just use a org plus start address.
A good plan would be to give the working boot loaders along with your code, this works most of the time, but not alway :( .
Also note, this is by no means a error in Alex Chadwick code, it happed to all bare metal OS dev's coding for the PI, its a change in the way the boot loader works, so your working on your code and everything works fine because your using the old loader file, then you release the code and thats when you find somethings been changed.
The main reason we use device like the pi, is that you hope if it works on one pi, it will work on another.
Its just part of being in the early stage's of the the PI's development, beta test to get it right for the masses.

It's possible for example to load yourself to the right address as long as you where not over writing yourself before you read yourself, if you get my meaning.
If this address was high enough, this would mean you code be loaded to zero or 0x8000 and it would work fine.

One thing i must say, you have the making of a good assembly coder, because you want to fully understand whats going on..
Batteries not included, Some assembly required.

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Fri Sep 21, 2012 1:25 pm

thanks for the responses guys - i will absorb them and be back soon

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Sun Sep 23, 2012 6:52 pm

Been reading a lot today;

To be honest - I have still not got a sufficient understanding of what is going on. I think my main problem is that I do not yet have a broad enough knowledge base in this area and so I am content for now to put the solution you put forward Simon and a similar one here from David Welch
https://github.com/dwelch67/raspberrypi ... zero_start to one side for now and maybe come back to the solutions later when I have a firmer grasp of the basics.

I can see that you are having to ask similar questions Simon https://github.com/raspberrypi/firmware/issues/36 and it seems as good a place as any to ask if there is any documentation for the firmware and boot process anywhere - I think the answer is here - but I think its worth pointing out for other newbies:
by jamesh » Sun Sep 23, 2012 6:32 pm
That's the Wiki pointed to from the front page of this website...please feel free to update/add information as necessary, it's a community effort.
For interested readers here is some boot information http://www.raspberrypi.org/phpBB3/viewt ... =63&t=6685

DexOS provided me with the answer to my burning question why did the program not work when I did not specify any addresses
So the address of data is 0x8000 plus size of text size
Now this is fine if loaded to zero, but if loaded to 0x8000 then the data is at real address is 0x8000 plus 0x8000 plus text.
So when it try to loaded it from "0x8000 plus size of text" it will most likely find a lot of zeros.

You can try this by adding 0x8000 to the reg that holds the data's address.
This is indeed the case the code from ok5's main method where is loads the data is now:

Code: Select all

	/* Load data at label pattern in to r4 */
	ptrn .req r4
	ldr ptrn,=pattern
	add ptrn,ptrn,#0x8000
	ldr ptrn,[ptrn]
The program works fine - the data is seemly shifted by 0x8000 - I do not specify any addresses at all and let the bootloader load the kernel.img where ever it likes - ofc I assume at 0x8000 given what I have read. Here is the ld script now.

Code: Select all

SECTIONS {

	.init : {
		*(.init)
	}
	
	.text : {
		*(.text)
	}
	
	.data : {
		*(.data)
	}
...
}
So I either have to use

Code: Select all

.init 0x8000 : {
or I have to add 0x8000 to the address of the data in the code for the thing to work, without going in to a solution like Simon provided above. I guess I have finally figured out what you mean by relative addresses DexOS - I suspect my code is being loaded in to 0x8000 by default and it assumes it is running at 0x0000 by default - making either change above tells my code that it is shifted by 0x8000 and is as such a relative address.

Thanks for your help guys.
Last edited by stevendodd on Sun Sep 23, 2012 7:08 pm, edited 3 times in total.

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Sun Sep 23, 2012 7:03 pm

I can only guess the GetGpioAddress is absolute because its part of the firmware....

Code: Select all

/*------------------------------------------------------------------------------
* Return the physical address of the GPIO region into r0.
------------------------------------------------------------------------------*/
.globl GetGpioAddress
GetGpioAddress:
	ldr r0,=0x20200000
	mov pc,lr

stevendodd
Posts: 14
Joined: Sun Jun 10, 2012 3:11 pm

Re: Baking Pi

Sun Sep 23, 2012 8:16 pm

For others just starting out with Baking PI - here is some more interesting and relevant information from another thread in this forum http://www.raspberrypi.org/phpBB3/viewt ... 72&t=15387

Dasaan
Posts: 7
Joined: Mon Sep 24, 2012 6:34 pm

Re: Baking Pi

Mon Sep 24, 2012 6:48 pm

OK01-05 all went fairly smoothly and Screen01 worked after much debugging but I am left wondering one thing:
In the data section in the framebuffer.s file (from the sample answer) you use

Code: Select all

.align 12
however the data actually appears to be aligned in 4 byte chunks is there a reason for this that I'm not seeing? Oddly the tutorial text even explicitly states that the data is aligned in 4 byte chunks.

Interestingly I tried changing the alignment to 4 and I no longer need to remove the HDMI cable and re-insert it to make the black screen disappear.

All in all a fun tutorial, I'm looking forward to working on the rest of the lessons. Will there be more in the future?

User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: Baking Pi

Mon Sep 24, 2012 8:15 pm

Dasaan wrote:OK01-05 all went fairly smoothly and Screen01 worked after much debugging but I am left wondering one thing:
In the data section in the framebuffer.s file (from the sample answer) you use

Code: Select all

.align 12
however the data actually appears to be aligned in 4 byte chunks is there a reason for this that I'm not seeing? Oddly the tutorial text even explicitly states that the data is aligned in 4 byte chunks.

Interestingly I tried changing the alignment to 4 and I no longer need to remove the HDMI cable and re-insert it to make the black screen disappear.

All in all a fun tutorial, I'm looking forward to working on the rest of the lessons. Will there be more in the future?
See here: http://www.raspberrypi.org/phpBB3/viewt ... 39#p174539
Batteries not included, Some assembly required.

MirceaM
Posts: 1
Joined: Mon Sep 24, 2012 2:27 pm

Running the BakingPi tutorial in QEMU

Wed Sep 26, 2012 11:02 am

Hi,

I was wondering if anyone managed to run the tutorial examples in QEMU on windows.I am able to run the Raspbian image without problems like this :

qemu-system-armw.exe -M versatilepb -cpu arm1176 -hda 2012-08-16-wheezy-raspbian.img -kernel kernel-qemu -m 192 -append "root=/dev/sda2"

However when I do this:
qemu-system-armw.exe -M versatilepb -cpu arm1176 -kernel kernel.img -m 192

where kernel.img is the output of the screen04 example I get nothing on the screen.

Did anybody here go this path before ?

Regards,
Mircea

User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: Running the BakingPi tutorial in QEMU

Wed Sep 26, 2012 3:47 pm

MirceaM wrote:Hi,

I was wondering if anyone managed to run the tutorial examples in QEMU on windows.I am able to run the Raspbian image without problems like this :

qemu-system-armw.exe -M versatilepb -cpu arm1176 -hda 2012-08-16-wheezy-raspbian.img -kernel kernel-qemu -m 192 -append "root=/dev/sda2"

However when I do this:
qemu-system-armw.exe -M versatilepb -cpu arm1176 -kernel kernel.img -m 192

where kernel.img is the output of the screen04 example I get nothing on the screen.

Did anybody here go this path before ?

Regards,
Mircea
I am 99% sure it will not be emulating GPU firmware, so bare metal screen output will not work.
I read some where that the Pi Risc OS does not work too.

It would not be that hard emulate the mailbox functions, so it should be available soon.
Batteries not included, Some assembly required.

jeremyp
Posts: 9
Joined: Wed Sep 26, 2012 3:58 pm

Re: Baking Pi

Wed Sep 26, 2012 4:16 pm

Hi, I've just been scanning through this thread because I am running through the BakingPi tutorial but converting the examples into C as I go (at some point, I'll post my code - so far I have everything up to and including tutorial 4 working).

Anyway, I noticed that there seems to be a lot of grief with getting the dev environment working for some people. I'm on OS X and I chose to use the MacPorts version. Install MacPorts from here:

http://www.macports.org/install.php

If you use the package installer, it will automatically amend your .profile to set the PATH variable correctly. Once you have done that, open a terminal and install arm-none-eabi-gcc

Code: Select all

sudo port install arm-none-eabi-gcc
This gives you a slightly older version of gcc than the Yagarto port but it seems to work and there is no messing about with the path or 32 bit libraries.

clone2148
Posts: 3
Joined: Thu Oct 11, 2012 6:59 am

Re: Baking Pi

Thu Oct 11, 2012 7:04 am

HELP!

Thanks for the project, Alex. I downloaded the test OS Coloured CLI, and extracted and everything, but I got an error in the picture. I did not modify the source directory, example01. Can you possibly help?
Attachments
help.png
screenshot of error
help.png (29.09 KiB) Viewed 5232 times

User avatar
Chadderz
Posts: 64
Joined: Thu Aug 30, 2012 12:50 pm
Location: Cambridge, UK

Re: Baking Pi

Thu Oct 11, 2012 7:43 am

Looks like you don't have libcsud.a which should be in the same directory as the makefile. This is my mistake; it should be in the archive of example01. libcsud.a is the USB driver used to get keyboard input. If you don't have it, you can find it in the 'Template for USB Operating System' on the downloads page.

clone2148
Posts: 3
Joined: Thu Oct 11, 2012 6:59 am

Re: Baking Pi

Fri Oct 12, 2012 3:50 am

Chadderz wrote:Looks like you don't have libcsud.a which should be in the same directory as the makefile. This is my mistake; it should be in the archive of example01. libcsud.a is the USB driver used to get keyboard input. If you don't have it, you can find it in the 'Template for USB Operating System' on the downloads page.
You might want to put that in troubleshooting.

clone2148
Posts: 3
Joined: Thu Oct 11, 2012 6:59 am

Re: Baking Pi

Sat Oct 13, 2012 5:20 am

Thanks! i moved the driver, and it compiled right :D. Unfortunately, I only tried this on my slow Windows netbook. I added yagarto to my path, so yagarto works; but more compiling errors! Here's a screenshot. Can you help?
Attachments
Screen Shot 2012-10-12 at 10.17.37 PM.png
Error on Mac terminal
Screen Shot 2012-10-12 at 10.17.37 PM.png (26.44 KiB) Viewed 5173 times

User avatar
Chadderz
Posts: 64
Joined: Thu Aug 30, 2012 12:50 pm
Location: Cambridge, UK

Re: Baking Pi

Sat Oct 13, 2012 6:49 am

Could it be that the build directory doesn't exist?

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Baking Pi

Sat Oct 13, 2012 12:08 pm

Nah, that's a "fail to find the toolchain" issue.

gertk
Posts: 52
Joined: Mon Aug 29, 2011 9:08 am

Re: Baking Pi

Tue Oct 23, 2012 6:08 pm

Tried the OK lessons 0-5 with succes led blinking etc. but I cannot get any of the screen lessons to work.
None of them gives any output, neither HDMI nor AV
Added a config.txt to my Fedora SD card setup and it seems to use the settings I have made there (simple 640x480 at 60 Hz) as it boots up and displays in [email protected] so far so good. (without the config,txt it boots up in native 1280x1024 mode of the monitor)

Then I tried compiling the lessons screen 01 to 04 and even though compilation gives no errors the result is the same after copying the kernel to the SD card: a blank AV output screen on nothing on the HDMI...

Compiling on Ubuntu 10.04 LTS and my monitor is a 1280x1024 Acer with a HDMI to DVI cable

Return to “Bare metal, Assembly language”