1, let Aps do something visually
Ap is 'Application processor'.
Following a power-up of an MP system, system hardware dynamically selects one of the processors on the system bus as the BSP. The remaining processors as APs. The BSP executes the BIOS's boot-strap code, and then 0x7c00, and then keeps straight on just as single-core processor in old days.
However, the Aps only do a minimal self-configuration, then halt¹ and wait for a STAT-UP signal(usually from BSP processor).
What we want is to let Aps do something we can see with eyes. How do you think of this code snippet:
Code: Select all
inc byte [cpu_count]
mov bx, 0xb800
mov ds, bx
l: inc [cpu_count]
jmp l
cpu_count: db 0
The way distributing a piece of code to one(or more) processor core for execution is a little complex, but we can play tricks:
We know, during the POST phase, BIOS had invoked all Aps and let them run a piece of instructions. So, we write our code there.
Open bochs2.6²/bios/rombios32start.S, you can find bios's AP-boot-code:
Code: Select all
smp_ap_boot_code_start:
cli
...
12:
lock incw smp_cpus
1:
hlt
jmp 1b
We add our code here:
Code: Select all
smp_ap_boot_code_start:
...
lock incw smp_cpus /* smp_cpus++*/
mov smp_cpus, %si /* si = smp_cpus */
shl $1, %si /* si *= 2*/
mov $0xb800, %bx
mov %bx, %ds
1:
incb 0(%si)
/*hlt*/
jmp 1b
Now, All work is done. We just need to recompile bochs, and we should see what we expect after bochs is power on.
here are some tips for the recompilation:
1, in fact, what we recompile is not bochs, it's 'rom-bios-latest' which is a standalone image seperate from bochs.
run: make -C bios/
2. you may need install bcc.
run: sudo apt-get install bcc
3, don't foget to run 'sudo make install' to send 'rom-bios-latest' to correct path.
Now, run bochs..
...
You may be disappointed: we see only one chracter position on screen do cyclical changing.
If you have a little knowledge about smp, you should notice an error in the begining. The bug hides between the two lines:
Code: Select all
lock incw smp_cpus /* smp_cpus++*/
mov smp_cpus, %si /* si = smp_cpus */
Assume core1 finished executing the first line, and begins executing the second line, However, Just at this point, core2 occupies the system bus to run 'lock incw smp_cpus'(he has probably been blocked for a long time due to core1's lock instruction), so core1 has to wait to obtain memory access. But, when core2 gives up the system bus, core3 occupies...
Finally, the value of 'smp_cpus' fetched by core1 is not what he want. And, all cores get a wrong value, except the last core.
It is Just what we see: only the fourth chacter on screen do cyclical changing.
The solution is easy: Use a 'lock'. I won't write here how to implement a lock or semaphore, there are many on the net. We have completed the most interesting part.
1, halt, not 'hlt'
2, my bochs verion is 2.6, configured as 2x2 cores. and my environment is:
ubuntu 12.04 LTS
gcc 4.6.3
-----------------------
welcome to point out mistakes in my post, including some english grammer you find strange.