├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── boot
├── Alpha.bin
└── config.txt
├── doc
└── img
│ ├── gdb-fileio.svg
│ ├── logo-alpha.svg
│ ├── logo-farjump.svg
│ ├── rpi-1aplus-wiring.jpeg
│ ├── rpi-embedded-dev.svg
│ └── rpi-mmap.svg
├── run.gdb
├── scripts
├── config.sh
├── install-rpi-boot.sh
├── install-toolchain.sh
├── lib
│ └── sh
│ │ └── utils.sh
└── update-readme.sh
├── sdk
├── Alpha.specs
├── CPU_init.c
├── CPU_init.o
├── CPU_init_util.S
├── CPU_init_util.o
├── CPU_start.S
├── CPU_start.o
├── Dockerfile
├── Makefile
├── alpha.gdb
├── armv6-core.xml
├── libalpha.a
├── libalpha
│ └── include
│ │ ├── alpha
│ │ └── fileio.h
│ │ └── gdb
│ │ └── fileio.h
├── libarm.a
├── libfileio.a
├── libfileio
│ └── src
│ │ ├── close.c
│ │ ├── errno.h
│ │ ├── exit.c
│ │ ├── fstat.c
│ │ ├── gettimeofday.c
│ │ ├── isatty.c
│ │ ├── lseek.c
│ │ ├── open.c
│ │ ├── read.c
│ │ ├── stat.c
│ │ ├── unlink.c
│ │ └── write.c
└── link.ld
└── src
├── hello-world
└── HelloWorld.c
├── raytracer
├── Raytracing.c
├── Raytracing.h
├── VC.c
├── VC.h
├── VC_aligned_buffer.S
└── main.c
└── semihosting
├── farjump-logo.c
└── semihosting.c
/.gitignore:
--------------------------------------------------------------------------------
1 | boot/bootcode.bin
2 | boot/start.elf
3 | *.map
4 | *.elf
5 | kernel.img
6 | kernel.dbg
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | FARJUMP SAS ("FARJUMP"), FOR AND ON BEHALF OF ITSELF AND ITS
2 | SUBSIDIARIES AND AFFILIATES UNDER COMMON CONTROL, IS WILLING TO
3 | LICENSE THE SOFTWARE TO YOU ONLY UPON THE CONDITION THAT YOU ACCEPT
4 | ALL OF THE TERMS CONTAINED IN THIS BINARY CODE LICENSE AGREEMENT AND
5 | SUPPLEMENTAL LICENSE TERMS (COLLECTIVELY "AGREEMENT"). PLEASE READ THE
6 | AGREEMENT CAREFULLY. BY COPYING OR USING THE SOFTWARE YOU ACKNOWLEDGE
7 | THAT YOU HAVE READ THE TERMS AND AGREE TO THEM. IF YOU ARE AGREEING TO
8 | THESE TERMS ON BEHALF OF A COMPANY OR OTHER LEGAL ENTITY, YOU
9 | REPRESENT THAT YOU HAVE THE LEGAL AUTHORITY TO BIND THE LEGAL ENTITY
10 | TO THESE TERMS. IF YOU DO NOT HAVE SUCH AUTHORITY, YOU MUST NOT USE
11 | THE SOFTWARE.
12 |
13 | 1. Words in the singular mean and include the plural and vice
14 | versa. Words in the masculine gender include the feminine gender and
15 | vice versa. Words in the neuter gender include the masculine gender
16 | and the feminine gender and vice versa.
17 |
18 | "License" shall mean the terms and conditions for use,
19 | reproduction, and distribution as defined by this document.
20 |
21 | "Licensor" shall mean the copyright owner or entity authorized by
22 | the copyright owner that is granting the License.
23 |
24 | "Legal Entity" shall mean the union of the acting entity and all
25 | other entities that control, are controlled by, or are under
26 | common control with that entity. For the purposes of this
27 | definition, "control" means (i) the power, direct or indirect, to
28 | cause the direction or management of such entity, whether by
29 | contract or otherwise, or (ii) ownership of fifty percent (50%) or
30 | more of the outstanding shares, or (iii) beneficial ownership of
31 | such entity.
32 |
33 | "You" (or "Your") shall mean an individual or Legal Entity exercising
34 | permissions granted by this License.
35 |
36 | "Source" form shall mean the preferred form for making
37 | modifications, including but not limited to software source code,
38 | documentation source, and configuration files.
39 |
40 | "Object" form shall mean any form resulting from mechanical
41 | transformation or translation of a Source form, including but not
42 | limited to compiled object code, generated documentation, and
43 | conversions to other media types.
44 |
45 | "Software" means Alpha in binary form that you copied, downloaded,
46 | installed or used, any other machine readable materials
47 | (including, but not limited to, libraries, source files, header
48 | files, and data files), any updates or error corrections provided
49 | by Farjump, and any user manuals, programming guides and other
50 | documentation provided to you by Farjump under this Agreement. The
51 | use of Software in systems and solutions that provide dedicated
52 | functionality or designed for use in embedded or function-specific
53 | software applications, for example but not limited to: Software
54 | embedded in or bundled with Specialised Computers and Servers,
55 | defined below, is licensed under this Agreement.
56 |
57 | "Specialised Computers and Servers" means computer systems and
58 | solutions with dedicated functionality or designed for use in
59 | embedded or function-specific software applications, for example
60 | but not limited to: Software embedded in or bundled with industrial
61 | control systems, wireless mobile telephones, wireless handheld
62 | devices, kiosks, TV/STB, Blu-ray Disc devices, telematics and
63 | network control switching equipment, printers and storage
64 | management systems, and other related computers, including desktop
65 | and laptop computers, or servers, used for computing functions
66 | under end user control.
67 |
68 | "Contribution" shall mean any work of authorship, including the
69 | original version of the Work and any modifications or additions to
70 | that Work or Derivative Works thereof, that is intentionally
71 | submitted to Licensor for inclusion in the Work by the copyright
72 | owner or by an individual or Legal Entity authorized to submit on
73 | behalf of the copyright owner. For the purposes of this definition,
74 | "submitted" means any form of electronic, verbal, or written
75 | communication sent to the Licensor or its representatives,
76 | including but not limited to communication on electronic mailing
77 | lists, source code control systems, and issue tracking systems that
78 | are managed by, or on behalf of, the Licensor for the purpose of
79 | discussing and improving the Work, but excluding communication that
80 | is conspicuously marked or otherwise designated in writing by the
81 | copyright owner as "Not a Contribution."
82 |
83 | "Contributor" shall mean Licensor and any individual or Legal Entity
84 | on behalf of whom a Contribution has been received by Licensor and
85 | subsequently incorporated within the Work.
86 |
87 | "Work" shall mean the work of authorship, whether in Source or
88 | Object form, made available under the License, as indicated by a
89 | copyright notice that is included in or attached to the work.
90 |
91 | 2. Subject to the terms and conditions of this Agreement including,
92 | but not limited to, Farjump grants you a non-exclusive,
93 | non-transferable, limited license without license fees to reproduce
94 | and use internally the Software complete and unmodified for the sole
95 | purpose of running and using Alpha.
96 |
97 | 3. Software is copyrighted. All associated intellectual property
98 | rights is retained by Farjump and/or its licensors. Unless
99 | enforcement is prohibited by applicable law, you may not modify,
100 | reverse engineer, or decompile the Software in any manner through
101 | current or future available technologies. If you use the Software
102 | in dangerous applications, then you shall be responsible to take
103 | all appropriate fail-safe, backup, redundancy, and other measures
104 | to ensure its safe use. Farjump disclaims any express or implied
105 | warranty of fitness for such uses. No right, title or interest in
106 | or to any trademark, service mark, logo or trade name of Farjump or
107 | its licensors is granted under this Agreement.
108 |
109 | 4. Commercial Use of Softwares and Alpha for any commercial or
110 | production purpose is not licensed under this Agreement and you must
111 | obtain a separate license from Farjump.
112 |
113 | 5. Farjump grants you a non-exclusive, non-transferable, limited
114 | license without fees to reproduce internally and use internally the
115 | Software complete and unmodified for the purpose of designing,
116 | developing, and testing your programs. You may copy and distribute the
117 | Software in object code or executable form complete and unmodified and
118 | only bundled as part of, and for the sole purpose of running, your
119 | programs, under these present terms. Each time you distribute the
120 | Software, the recipient automatically receives a license from the
121 | original licensor to copy, distribute or modify the Software subject
122 | to these terms and conditions. You may not impose any further
123 | restrictions on the recipients' exercise of the rights granted
124 | herein. You are not responsible for enforcing compliance by third
125 | parties to this License.
126 |
127 | 6. Additional copyright notices and license terms applicable to
128 | portions of the Software are set forth in the NOTICE file. In
129 | addition to any terms and conditions of any third party
130 | opensource/freeware license identified in the NOTICE file, the
131 | disclaimer of warranty and limitation of liability shall apply to
132 | all Software in this distribution.
133 |
134 | 7. Submission of Contributions. Unless You explicitly state otherwise,
135 | any Contribution intentionally submitted for inclusion in the Work
136 | by You to the Licensor shall be under the terms and conditions of
137 | this License, without any additional terms or conditions.
138 | Notwithstanding the above, nothing herein shall supersede or modify
139 | the terms of any separate license agreement you may have executed
140 | with Licensor regarding such Contributions.
141 |
142 | 8. Subject to the terms and conditions of this License, each
143 | Contributor hereby grants to You a perpetual, worldwide,
144 | non-exclusive, no-charge, royalty-free, irrevocable (except as
145 | stated in this section) patent license to make, have made, use,
146 | offer to sell, sell, import, and otherwise transfer the Work, where
147 | such license applies only to those patent claims licensable by such
148 | Contributor that are necessarily infringed by their Contribution(s)
149 | alone or by combination of their Contribution(s) with the Work to
150 | which such Contribution(s) was submitted. If You institute patent
151 | litigation against any entity (including a cross-claim or
152 | counterclaim in a lawsuit) alleging that the Work or a Contribution
153 | incorporated within the Work constitutes direct or contributory
154 | patent infringement, then any patent licenses granted to You under
155 | this License for that Work shall terminate as of the date such
156 | litigation is filed.
157 |
158 | 11. Online support or maintenance is provided as part of this
159 | Agreement filling an issue at the following address
160 | https://github.com/farjump/raspberrypi/issues/.
161 |
162 | 12. BECAUSE THE SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO
163 | WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE
164 | LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS
165 | AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY
166 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
167 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
168 | FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
169 | PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE
170 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
171 | OR CORRECTION.
172 |
173 | 13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
174 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
175 | MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE
176 | LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
177 | INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
178 | INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS
179 | OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
180 | YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH
181 | ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
182 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
183 |
184 | END OF TERMS AND CONDITIONS
185 |
186 | Copyright 2017 Farjump, SAS.
187 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | toolchain := arm-none-eabi
2 | elfs := hello.elf raytracer.elf
3 |
4 | # Hello World
5 | sources/hello.elf := $(addprefix src/hello-world/, HelloWorld.c)
6 |
7 | # Raytracer
8 | sources/raytracer.elf := $(addprefix src/raytracer/, main.c Raytracing.c VC.c VC_aligned_buffer.S)
9 | libs/raytracer.elf := -lm
10 | cflags/raytracer.elf := -Og
11 |
12 | # Common Flags
13 | cflags := -specs=sdk/Alpha.specs -mfloat-abi=hard -mfpu=vfp -march=armv6zk -mtune=arm1176jzf-s -g3 -ggdb
14 | ldflags := -Wl,-Tsdk/link.ld -Lsdk -Wl,-umalloc
15 |
16 | .PHONY: all
17 | all: $(elfs)
18 |
19 | .PHONY: clean
20 | clean:
21 | rm -f $(elfs) $(addsuffix .map, $(basename $(elfs))) kernel.img kernel.dbg
22 |
23 | kernel.img: raytracer.elf
24 | $(toolchain)-objcopy -O binary $< $@
25 | $(toolchain)-objcopy --only-keep-debug $< $(basename $@).dbg
26 |
27 | .SECONDEXPANSION:
28 | $(elfs): $$(sources/$$@)
29 | $(toolchain)-gcc $(cflags) $(ldflags) -Wl,-Map,$(basename $@).map -o $@ $(cflags/$@) $^ $(libs/$@)
30 |
31 | .PHONY: shell
32 | define docker/build :=
33 | docker build -f sdk/Dockerfile --build-arg uid=$$(id -u) .
34 | endef
35 | shell:
36 | $(docker/build)
37 | docker run -it -v $$PWD:$$PWD -w $$PWD --privileged $$($(docker/build) -q)
38 |
39 | .PHONY: README.md
40 | README.md:
41 | ./scripts/update-readme.sh
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Alpha
4 | ======================
5 |
6 | [GDB] offers the best embedded software development experience by
7 | allowing you to remotely load, debug and test your programs and
8 | hardware/software interfaces. It feels like native programming thanks
9 | to a similar smooth "Edit-Compile-Run" cycle.
10 |
11 | [Alpha] is a system-level [GDB] server (aka "gdbstub" and "gdb stubs")
12 | allowing you to dynamically debug anything running in your hardware
13 | target, from bare metal software to OS-backed programs, including
14 | their threads, the underlying drivers, etc. All with a single GDB
15 | session and **without any JTAG probe**.
16 |
17 |
18 |
19 |
20 | This repository contains the freemium distribution of [Alpha] for any
21 | version of the Raspberry Pi.
22 |
23 |
24 |
25 | Table of Contents
26 | =================
27 |
28 | * [Use Cases](#use-cases)
29 | * [Bare Metal Programming](#bare-metal-programming)
30 | * [Benchmarking](#benchmarking)
31 | * [Writing drivers](#writing-drivers)
32 | * [High performance](#high-performance)
33 | * [Learning by doing](#learning-by-doing)
34 | * [Operating System Debugging](#operating-system-debugging)
35 | * [Multi-core Debugging](#multi-core-debugging)
36 | * [A convenient programming environment](#a-convenient-programming-environment)
37 | * [A bare metal C library](#a-bare-metal-c-library)
38 | * [List of delegated syscalls](#list-of-delegated-syscalls)
39 | * [List of implemented syscalls](#list-of-implemented-syscalls)
40 | * [A stack](#a-stack)
41 | * [An address space](#an-address-space)
42 | * [An extended GDB server](#an-extended-gdb-server)
43 | * [Exiting GDB resets the SoC](#exiting-gdb-resets-the-soc)
44 | * [Stopping the execution](#stopping-the-execution)
45 | * [Alpha-specific commands](#alpha-specific-commands)
46 | * [Installation](#installation)
47 | * [Alpha](#alpha)
48 | * [Wiring](#wiring)
49 | * [Examples](#examples)
50 | * [Hello World](#hello-world)
51 | * [Compiling](#compiling)
52 | * [Running](#running)
53 | * [Raytracer](#raytracer)
54 | * [Compiling](#compiling-1)
55 | * [Running](#running-1)
56 | * [Support](#support)
57 | * [Licensing](#licensing)
58 |
59 | Generated by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
60 |
61 |
62 |
63 | # Use Cases
64 |
65 | ## Bare Metal Programming
66 |
67 | Bare metal programming is ideal for benchmarking, high-performance
68 | programs & low-level prototyping.
69 |
70 | [Alpha] provides a **modern** & **convenient** bare metal programming
71 | environment:
72 |
73 | - A ready-to-use hardware state thanks to more advanced hardware
74 | initializations than what firmwares or bootloaders usually do,
75 | including the floating point unit, caches and a convenient address
76 | space. Note that only the 32-bit mode of the ARM architecture is
77 | supported and that other modes are part of our business-level
78 | plan. Please, [contact us for more
79 | details][contact-us].
80 |
81 | - The ability to run standard C programs bare metal. C library
82 | functions involving syscalls (`malloc`, `printf`, etc.) are
83 | delegated to [GDB] by [Alpha].
84 |
85 |
86 | ### Benchmarking
87 |
88 | The hardest part of benchmarking is understanding the results. And
89 | this is the main reason for running benchmarks bare metal:
90 |
91 | 1. Being alone running on the hardware to:
92 | - Avoid interferences of concurrent or parallel programs.
93 | - Be able to easily reach the best or worst cases.
94 |
95 | 1. Being at the closest possible level to the hardware/software
96 | interface to:
97 | - Understand perfectly what the hardware is doing.
98 | - Get rid of too high-level abstractions possibly hiding
99 | implementation details.
100 |
101 |
102 | ### Writing drivers
103 |
104 | The Raspberry Pi has a nice set of I/O interfaces (SPI, I2C, GPIO,
105 | USB, etc.) which makes it a good candidate to write the low-level
106 | parts of your drivers.
107 |
108 | You can easily write, debug and test your I/O peripheral driver just
109 | its hardware documentation and [GDB]. You can then integrate it in any
110 | OS driver API such as Linux, FreeRTOS, etc. Note that is a very good
111 | practice to be able to easily test a driver.
112 |
113 | Simply plug your I/O peripheral and get started:
114 |
115 | 1. You can start exploring the hardware/software interface through GDB
116 | memory [read] and [write] commands.
117 |
118 | 1. Focus on what really matters thanks a ready-to-use execution
119 | environment incluing supervisor-level execution privileges.
120 |
121 |
122 | ### High performance
123 |
124 | The highest levels of performance and responsiveness can be easily
125 | reached bare metal. Being alone on the machine, right above the
126 | hardware/software interface, allows to avoid time-consuming calls and
127 | to reach the fastest response times and throughputs.
128 |
129 |
130 | ### Learning by doing
131 |
132 | Learning embedded software usually comes at a price you can now avoid
133 | with this GDB-centric approach. No extra JTAG probe, no complex
134 | firmware & bootloader dependency and no complex tools. Here, it's a
135 | simple matter of powering on the Raspberry Pi and launching [GDB] to
136 | load a program and run/debug/test it using the same tools (GCC) and
137 | file formats (ELF) as usual native programming. [GDB] is the most
138 | famous debugging tool which is [much more than a simple
139 | debugger][time-to-blink-a-led].
140 |
141 | Moreover, [Alpha] can catch common programming errors such as memory
142 | access violations to stop the execution exactly where the mistake
143 | happened:
144 |
145 | ```text
146 | (gdb) monitor gdb/catch
147 | RST : no : Reset Exception
148 | UND : no : Undefined Instruction Exception
149 | SWI : no : Software Interrupt Exception
150 | PABRT : no : Prefetch Abort Exception
151 | DABRT : no : Data Abort Exception
152 | IRQ : no : IRQ (interrupt) Exception
153 | FIQR : no : FIQ (fast interrupt) Exception
154 | (gdb) monitor gdb/catch DABRT yes
155 | DABRT : yes : Data Abort Exception
156 | ```
157 |
158 | So have fun and enjoy exploring the GPU, enabling another core,
159 | communicating through USB, or whatever comes to your mind.
160 |
161 |
162 | ## Operating System Debugging
163 |
164 | OS-aware debugging is part of our business-level plan and is disabled
165 | in this version. Please, [contact us for more details][contact-us].
166 |
167 |
168 | ## Multi-core Debugging
169 |
170 | Multi-core debugging is part of our business-level plan and is
171 | disabled in this version. Please, [contact us for more
172 | details][contact-us].
173 |
174 |
175 | # A convenient programming environment
176 |
177 | ## A bare metal C library
178 |
179 | Running bare metal does not mean at all having to write everything
180 | from scratch and in assembly. This repository shows program examples
181 | written in C and involving calls to the C library, such as `printf()`
182 | and `scanf()`.
183 |
184 | The provided C library is the [newlib] (because it can be directly
185 | integrated into GCC), which relies on the POSIX syscalls. Some of them
186 | - the most useful ones when prototyping, benchmarking & testing - can
187 | be handled by GDB (see below), while others are implemented bare metal
188 | and others not at all.
189 |
190 |
191 | ### List of delegated syscalls
192 |
193 | Syscalls are delegated to [GDB] by [Alpha] through its remote
194 | protocol. Their number and their arguments are limited but it is
195 | enough to print convenience logs, write benchmark results into CSV
196 | files, etc.
197 |
198 | - open
199 | - close
200 | - read
201 | - write
202 | - lseek
203 | - rename
204 | - unlink
205 | - stat/fstat
206 | - gettimeofday
207 | - isatty
208 | - system
209 |
210 | ![GDB File I/O][img-gdb-fileio]
211 |
212 |
213 | ### List of implemented syscalls
214 |
215 | Syscalls that are implemented and can be used bare metal:
216 |
217 | - brk: requires a global symbol `_end` as beginning of the free
218 | area. We provide it through our linker script
219 | [`sdk/link.ld`](sdk/link.ld) as the end of the program.
220 |
221 |
222 | ### A stack
223 |
224 | The stack address is configured in the linker script through the
225 | `__stack` symbol. Its maximum size is thus the configured address
226 | minus the next non-free memory region.
227 |
228 |
229 | ## An address space
230 |
231 | [Alpha] maps a useful address space including the RAM and the
232 | memory-mapped I/Os:
233 |
234 |
235 |
236 |
237 | ## An extended GDB server
238 |
239 | ### Exiting GDB resets the SoC
240 |
241 | Resetting the hardware is a good practice to avoid side-effects and
242 | make things repeatable. **Correctly leaving GDB** sends a `kill`
243 | command to the target, which is translated by [Alpha] into a SoC
244 | reset, so you don't have to bother turning it off and on again to
245 | restart from scratch.
246 |
247 |
248 | ### Stopping the execution
249 |
250 | Asynchronously interrupt the Raspberry Pi while it is executing your
251 | program using the command `interrupt` or the `SIGINT` signal through
252 | the ctrlc keystroke.
253 |
254 | For example:
255 | ```text
256 | (gdb) continue
257 | Continuing.
258 | ^C
259 | Program received signal SIGSTOP, Stopped (signal).
260 | 0x0000921c in __ieee754_sqrt ()
261 | (gdb) # The execution is stopped
262 | ```
263 |
264 | ```text
265 | (gdb) continue &
266 | Continuing.
267 | (gdb) interrupt
268 | Program received signal SIGSTOP, Stopped (signal).
269 | 0x0000921c in __ieee754_sqrt ()
270 | (gdb) # The execution is stopped
271 | ```
272 |
273 | This feature requires external interrupts which must be unmasked
274 | (enabled) to allow them. Here is an example using GDB's built-in
275 | scripting:
276 |
277 | ```text
278 | (gdb) print /x $cpsr &= ~(1 << 7)
279 | $1 = 0x6000015f
280 | ```
281 |
282 | The raytracer example below uses it to be able to interrupt endless
283 | loop and quit GDB.
284 |
285 |
286 | ### Alpha-specific commands
287 |
288 | [Alpha] provides extra GDB commands accessible through the `monitor`
289 | command:
290 |
291 |
292 | ```text
293 | (gdb) monitor help
294 | help [COMMAND]
295 | Print help of all or help of COMMAND in parameter
296 |
297 | version
298 | Print version of Alpha Target
299 |
300 | mr8 ADDRESS [COUNT]
301 | Read COUNT or 1 8bit word at ADDRESS
302 |
303 | mr16 ADDRESS [COUNT]
304 | Read COUNT or 1 16bit word at ADDRESS
305 |
306 | mr32 ADDRESS [COUNT]
307 | Read COUNT or 1 32bit word at ADDRESS
308 |
309 | mw8 ADDRESS VALUE
310 | Write the 8bit word VALUE at ADDRESS
311 |
312 | mw16 ADDRESS VALUE
313 | Write the 16bit word VALUE at ADDRESS
314 |
315 | mw32 ADDRESS VALUE
316 | Write the 32bit word VALUE at ADDRESS
317 |
318 | fill32 ADDRESS COUNT VALUE
319 | Fill at ADDRESS COUNT 32bit word with VALUE
320 |
321 | gdb/wcet [yes|no]
322 | Print or set Alpha WCET mode
323 |
324 | gdb/catch
325 | Print the list of exceptions that can be caught by Alpha
326 |
327 | gdb/catch EXCEPTION [yes|no]
328 | Print or set/unset the catching of EXCEPTION
329 | ```
330 |
331 |
332 | # Installation
333 |
334 | ![GDB remote link with the Raspberry Pi][img-rpi-embedded-dev]
335 |
336 |
337 | ## Alpha
338 |
339 | Installing [Alpha] into your Raspberry Pi is very easy. You simply
340 | need to copy `boot/{Alpha.bin, config.txt}` into the boot partition of
341 | your Raspberry Pi' SD card. [Alpha] is then started by the Raspberry
342 | Pi's bootloader from its SD card according to `config.txt` directives
343 | (load & start address).
344 |
345 | The script [`scripts/install-rpi-boot.sh`](scripts/install-rpi-boot.sh)
346 | creates a new SD card from scratch by:
347 |
348 | 1. Downloading the officially distributed firmware and bootloader into `boot/`.
349 | 1. Formatting the SD card in FAT32 (without partitioning it).
350 | 1. Copying every files in `boot/` into the SD card.
351 |
352 | ```text
353 | $ ./scripts/install-rpi-boot.sh /dev/
354 | [+] Downloading the Raspberry Pi's firmware version 1.20161215
355 | ######################################################################## 100.0%
356 | ######################################################################## 100.0%
357 | [+] Temporarily mounting `/dev/` into `/tmp/rpi-sdcard-mountpoint`
358 | [+] Installing the RPi firmware and the Alpha debugger
359 | 'boot/bootcode.bin' -> '/tmp/rpi-sdcard-mountpoint/bootcode.bin'
360 | 'boot/start.elf' -> '/tmp/rpi-sdcard-mountpoint/start.elf'
361 | 'boot/Alpha.bin' -> '/tmp/rpi-sdcard-mountpoint/Alpha.bin'
362 | 'boot/config.txt' -> '/tmp/rpi-sdcard-mountpoint/config.txt'
363 | [+] Checking the integrity
364 | /tmp/rpi-sdcard-mountpoint/bootcode.bin: OK
365 | /tmp/rpi-sdcard-mountpoint/start.elf: OK
366 | /tmp/rpi-sdcard-mountpoint/Alpha.bin: OK
367 | [+] Un-mounting `/tmp/rpi-sdcard-mountpoint`
368 | [+] Your SD card is ready!
369 | [+] You can now insert it into the RPi and use Alpha through the RPI's Mini-UART
370 | ```
371 |
372 |
373 | ## Wiring
374 |
375 | Using GDB in client/server mode requires a link between your
376 | workstation and your Raspberry Pi. For portability reasons, we chose
377 | the Raspberry Pi's Mini-UART. You can connect it to your workstation
378 | using a USB-UART TTL **3.3V** (not 5V) converter.
379 |
380 | Here are some random converter references:
381 | - [Adafruit's TTL cable](https://www.adafruit.com/product/954)
382 | - [FTDI's TTL cable `TTL-232R-3V3`](https://shop.clickandbuild.com/cnb/shop/ftdichip?productID=53&op=catalogue-product_info-null&prodCategoryID=296).
383 | - Or do it yourself using a USB-UART TTL 3.3V converter, 3 jumper cables and 1 USB cable.
384 |
385 |
386 |
387 |
388 |
389 |
390 | # Examples
391 |
392 | Two bare metal programs are provided as examples: a hello world
393 | including bare metal calls to `printf()` and `scanf()`, and a
394 | raytracer using the GPU.
395 |
396 | Note that we use docker to produce our development environments and
397 | build a Debian image with the expected tools, including [the GCC
398 | toolchain for the ARM architecture][arm-toolchain]. The Makefile
399 | command `make shell` builds the docker image according to
400 | [`sdk/Dockerfile`](sdk/Dockerfile). It is up to you to use it or use
401 | instead your own setup (and you can find the list of required
402 | dependencies in the [`sdk/Dockerfile`](sdk/Dockerfile)).
403 |
404 | ```bash
405 | $ make shell
406 | docker build -f sdk/Dockerfile --build-arg uid=$(id -u) .
407 | Sending build context to Docker daemon 3.843 MB
408 | Step 1 : FROM debian:stretch
409 | ...
410 | Successfully built 730a81db9233
411 | user@3979cd200f4b:/home/user/farjump/raspberry-pi$ # Let's get started
412 | ```
413 |
414 | [GDB] is then used to remotely load the program. The file
415 | [`run.gdb`](run.gdb) is a helper GDB script:
416 | 1. Connecting to the target through the TTY interface of the TTL cable.
417 | 1. Loading the ELF executable.
418 | 1. Starting running the program until entering the `main()` function.
419 |
420 | **You need to replace the serial interface** `/dev/ttyUSB0` **with
421 | yours** (usually `/dev/ttyUSB*`, `/dev/ttyACM*`, `/dev/cu.*`
422 | ... according to your OS).
423 |
424 | ```bash
425 | $ arm-none-eabi-gdb -x run.gdb
426 | ```
427 |
428 |
429 | ## Hello World
430 |
431 | ### Compiling
432 |
433 | ```bash
434 | $ make hello.elf
435 | arm-none-eabi-gcc -specs=sdk/Alpha.specs -mfloat-abi=hard -mfpu=vfp -march=armv6zk -mtune=arm1176jzf-s -g3 -ggdb -Wl,-Tsdk/link.ld -Lsdk -Wl,-umalloc -Wl,-Map,hello.map -o hello.elf src/hello-world/HelloWorld.c
436 | ```
437 |
438 | ### Running
439 |
440 | ```text
441 | user@f76db25a61c1:/home/user/farjump/raspberry-pi$ arm-none-eabi-gdb -x run.gdb hello.elf
442 | Reading symbols from hello.elf...done.
443 | 0x07f10570 in ?? ()
444 | Loading section .entry, size 0x14f lma 0x8000
445 | Loading section .text, size 0x11ed4 lma 0x8150
446 | Loading section .init, size 0x18 lma 0x1a024
447 | Loading section .fini, size 0x18 lma 0x1a03c
448 | Loading section .rodata, size 0x50c lma 0x1a058
449 | Loading section .ARM.exidx, size 0x8 lma 0x1a564
450 | Loading section .eh_frame, size 0x4 lma 0x1a56c
451 | Loading section .init_array, size 0x8 lma 0x2a570
452 | Loading section .fini_array, size 0x4 lma 0x2a578
453 | Loading section .jcr, size 0x4 lma 0x2a57c
454 | Loading section .data, size 0x9ac lma 0x2a580
455 | Start address 0x820c, load size 77607
456 | Transfer rate: 10 KB/sec, 892 bytes/write.
457 | Temporary breakpoint 1 at 0x832c: file src/hello-world/HelloWorld.c, line 7.
458 |
459 | Temporary breakpoint 1, main () at src/hello-world/HelloWorld.c:7
460 | 7 printf("Enter a string: \e[?25h");
461 |
462 | (gdb) # We have reached the main() function, have fun now ;)
463 | (gdb) continue
464 | Continuing.
465 |
466 | Enter a string: Farjumper
467 | RPi says "Hello Farjumper!"
468 |
469 | Program received signal SIGTRAP, Trace/breakpoint trap.
470 | _exit (rc=0) at SYSFILEIO/MAKEFILE/../SOURCE/SYSFILEIO_EXIT.c:11
471 | 11 SYSFILEIO/MAKEFILE/../SOURCE/SYSFILEIO_EXIT.c: No such file or directory.
472 |
473 | (gdb) quit
474 | user@f76db25a61c1:/home/user/farjump/raspberry-pi$ # The RPi resets.
475 | ```
476 |
477 |
478 | ## Raytracer
479 |
480 | ### Compiling
481 |
482 | ```bash
483 | $ make raytracer.elf
484 | arm-none-eabi-gcc -specs=sdk/Alpha.specs -mfloat-abi=hard -mfpu=vfp -march=armv6zk -mtune=arm1176jzf-s -g3 -ggdb -Wl,-Tsdk/link.ld -Lsdk -Wl,-umalloc -Wl,-Map,raytracer.map -o raytracer.elf -Og src/raytracer/main.c src/raytracer/Raytracing.c src/raytracer/VC.c src/raytracer/VC_aligned_buffer.S -lm
485 | ```
486 |
487 |
488 | ### Running
489 |
490 | If you want to watch the video output, plug first a screen to your RPi's HDMI port ;)
491 |
492 | ```text
493 | user@f76db25a61c1:/home/user/farjump/raspberry-pi$ arm-none-eabi-gdb -x run.gdb raytracer.elf
494 | Reading symbols from raytracer.elf...done.
495 | 0x07f10570 in ?? ()
496 | Loading section .entry, size 0x14f lma 0x8000
497 | Loading section .text, size 0x1890 lma 0x8150
498 | Loading section .init, size 0x18 lma 0x99e0
499 | Loading section .fini, size 0x18 lma 0x99f8
500 | Loading section .rodata, size 0xc lma 0x9a10
501 | Loading section .ARM.exidx, size 0x8 lma 0x9a1c
502 | Loading section .eh_frame, size 0x4 lma 0x9a24
503 | Loading section .init_array, size 0x8 lma 0x19a28
504 | Loading section .fini_array, size 0x4 lma 0x19a30
505 | Loading section .jcr, size 0x4 lma 0x19a34
506 | Loading section .data, size 0x590 lma 0x19a38
507 | Start address 0x820c, load size 8135
508 | Transfer rate: 10 KB/sec, 451 bytes/write.
509 | Temporary breakpoint 1 at 0x8320: file src/raytracer/main.c, line 221.
510 |
511 | Temporary breakpoint 1, main () at src/raytracer/main.c:221
512 | 221 {
513 |
514 | (gdb) # Enable external interrupts to be able to stop the execution later
515 | (gdb) print /x $cpsr &= ~(1 << 7)
516 | $1 = 0x6000015f
517 |
518 | (gdb) continue
519 | Continuing.
520 | ^C
521 | Program received signal SIGSTOP, Stopped (signal).
522 | 0x0000921c in __ieee754_sqrt ()
523 |
524 | (gdb) quit
525 | user@f76db25a61c1:/home/user/farjump/raspberry-pi$ # The RPi resets.
526 | ```
527 |
528 |
529 | # Support
530 |
531 | Support is provided through this repository's [issue board](https://github.com/farjump/raspberry-pi/issues).
532 | Feel free to also [contact us][contact-us].
533 |
534 |
535 | # Licensing
536 |
537 | See [LICENSE](LICENSE) for the full license text.
538 |
539 |
540 | [Alpha]: https://farjump.io
541 | [GDB]: https://sourceware.org/gdb/current/onlinedocs/gdb/Summary.html
542 | [newlib]: https://sourceware.org/newlib/
543 | [write]: https://sourceware.org/gdb/current/onlinedocs/gdb/Assignment.html
544 | [read]: https://sourceware.org/gdb/onlinedocs/gdb/Memory.html
545 | [time-to-blink-a-led]: https://www.youtube.com/watch?v=niSBhjHa22I
546 | [contact-us]: https://farjump.io/contact-us
547 | [img-gdb-fileio]: https://cdn.rawgit.com/farjump/raspberry-pi/master/doc/img/gdb-fileio.svg
548 | [img-rpi-embedded-dev]: https://cdn.rawgit.com/farjump/raspberry-pi/master/doc/img/rpi-embedded-dev.svg
549 | [arm-toolchain]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
550 |
--------------------------------------------------------------------------------
/boot/Alpha.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/boot/Alpha.bin
--------------------------------------------------------------------------------
/boot/config.txt:
--------------------------------------------------------------------------------
1 | kernel=Alpha.bin
2 | kernel_address=0x07F08000
3 |
--------------------------------------------------------------------------------
/doc/img/logo-farjump.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/doc/img/rpi-1aplus-wiring.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/doc/img/rpi-1aplus-wiring.jpeg
--------------------------------------------------------------------------------
/doc/img/rpi-embedded-dev.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/run.gdb:
--------------------------------------------------------------------------------
1 | source sdk/alpha.gdb
2 |
3 | # Connect to the RPi
4 | set serial baud 115200
5 | target remote /dev/ttyUSB0
6 |
7 | # Load the executable in the target
8 | # By default, the loaded file is the one GDB debugs, given as argument
9 | # to gdb or using the command file.
10 | load
11 |
12 | # Run untile reaching main
13 | tbreak main
14 | continue
15 |
--------------------------------------------------------------------------------
/scripts/config.sh:
--------------------------------------------------------------------------------
1 | # configuraion
2 | cfg_rpi_fw_version='1.20161215'
3 | cfg_rpi_fw_baseurl="https://github.com/raspberrypi/firmware/raw/$cfg_rpi_fw_version/boot/"
4 | cfg_sdcard_mountpoint='/tmp/rpi-sdcard-mountpoint'
5 | cfg_bootcode_download_sha256=db7bd566617565efe3bedfa4d69eaa2ab1d5d73b1de55c0d3bd67e879d2eb7e9
6 | cfg_start_download_sha256=38a00a91eeafe87ddec042e64025745760dcc77cac2bff0d87a28b11ddce871e
7 | cfg_alpha_sha256=37569ef914ad3ea535d2d0054634f3137522502ab24648801c899be93d759a5b
8 | cfg_arm_toolchain_url=https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2016q4/gcc-arm-none-eabi-6_2-2016q4-20161216-linux.tar.bz2
9 | cfg_arm_toolchain_path_default=/opt/arm-none-eabi
10 |
--------------------------------------------------------------------------------
/scripts/install-rpi-boot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # immediately exit on any unhandled error
4 | set -e
5 |
6 | # current working directory
7 | cwd=${0%/*}
8 |
9 | . $cwd/lib/sh/utils.sh
10 |
11 | . $cwd/config.sh
12 |
13 | #
14 | # Print the help message
15 | #
16 | cmd_help() {
17 | cat <
19 |
20 | Download and install into the block device the Raspberry Pi's firmware
21 | & bootloader, and Farjump's Alpha. The block device must
22 | contain a FAT file-system.
23 |
24 | Note that the block device is mounted and finally unmounted during the
25 | execution of this scripts, which requires root privileges.
26 |
27 | EXAMPLE
28 | \$ mkfs.vfat -F 32 -n RPI /dev/sdX # /!\ erases everything in sdX
29 | \$ $0 /dev/sdX
30 | EOF
31 | }
32 |
33 | #
34 | # Mount the SD card block device `$1` into `$cfg_sdcard_mountpoint`.
35 | #
36 | cmd_mount() {
37 | dev="$1"
38 | log_info "Temporarily mounting \`$dev\` into \`$cfg_sdcard_mountpoint\`"
39 | mkdir -p $cfg_sdcard_mountpoint
40 | sudo mount -t vfat -o rw,umask=0000 "$dev" $cfg_sdcard_mountpoint
41 | }
42 |
43 | #
44 | # Unmount `$cfg_sdcard_mountpoint`
45 | #
46 | cmd_unmount() {
47 | log_info "Un-mounting \`$cfg_sdcard_mountpoint\`"
48 | sync $cfg_sdcard_mountpoint/*
49 | sudo umount $cfg_sdcard_mountpoint
50 | }
51 |
52 | #
53 | # Download official firmwares from the RPi repo
54 | #
55 | cmd_download_files() {
56 | dst="$1"
57 | if ! cmd_check_fw_sha256 $dst --quiet 1>&- 2>&-; then
58 | log_info "Downloading the Raspberry Pi's firmware version $cfg_rpi_fw_version"
59 | (
60 | cd $dst
61 | curl -fSL --remote-name-all --progress-bar $cfg_rpi_fw_baseurl/start.elf $cfg_rpi_fw_baseurl/bootcode.bin
62 | )
63 | fi
64 | }
65 |
66 | #
67 | # Copy downloaded files into the mounted SD card and check the file integrity.
68 | #
69 | cmd_copy_files() {
70 | src=$1
71 | log_info "Installing the RPi firmware and the Alpha debugger"
72 | cp -fv $src/bootcode.bin $src/start.elf $src/Alpha.bin $src/config.txt $cfg_sdcard_mountpoint
73 | log_info "Checking the integrity"
74 | cmd_check_fw_sha256 $cfg_sdcard_mountpoint
75 | echo "$cfg_alpha_sha256 $cfg_sdcard_mountpoint/Alpha.bin" | sha256sum -c -
76 | }
77 |
78 | #
79 | # Check the sha256sum of the firmware stored in $1.
80 | # Optionally pass an extra sha256sum argument as $2.
81 | #
82 | cmd_check_fw_sha256() {
83 | ( echo "$cfg_bootcode_download_sha256 $1/bootcode.bin" | sha256sum -c $2 - ) || return 1
84 | echo "$cfg_start_download_sha256 $1/start.elf" | sha256sum -c $2 -
85 | }
86 |
87 | #
88 | # script entry function
89 | #
90 | cmd() {
91 | while [ $# -gt 0 ]; do
92 | case $1 in
93 | -h|--help)
94 | cmd_help
95 | return 1 # note: doing this makes only one --help message possible
96 | ;;
97 |
98 | -*)
99 | log_error "$0: illegal option −− $1"
100 | return 1
101 | ;;
102 |
103 | --)
104 | shift
105 | ;;
106 |
107 | *)
108 | [ -n "$dev" ] && log_info "warning: ignoring \`$dev\`"
109 | dev="$1"
110 | shift
111 | ;;
112 | esac
113 | done
114 |
115 | if [ -z "$dev" ]; then
116 | log_error " missing block device argument"
117 | return 1
118 | fi
119 |
120 | src='boot'
121 | cmd_download_files $src
122 | cmd_mount "$dev"
123 | trap 'cmd_unmount "$dev"' INT QUIT KILL ABRT
124 | if ! cmd_copy_files $src; then
125 | cmd_unmount "$dev"
126 | return 1
127 | fi
128 | cmd_unmount "$dev"
129 | log_info 'Your SD card is ready!'
130 | log_info "You can now insert it into the RPi and use Alpha through the RPI's Mini-UART"
131 | return 0
132 | }
133 |
134 | cmd $@
135 |
--------------------------------------------------------------------------------
/scripts/install-toolchain.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # immediately exit on any unhandled error
4 | set -e
5 |
6 | # current working directory
7 | cwd=${0%/*}
8 |
9 | . $cwd/lib/sh/utils.sh
10 |
11 | . $cwd/config.sh
12 |
13 | #
14 | # Print the help message
15 | #
16 | cmd_help() {
17 | cat <&- 2>&-
71 | $opt_toolchain_path/bin/arm-none-eabi-gdb -v 1>&- 2>&-
72 | log_info "The toolchain has been successfully installed."
73 |
74 | return 0
75 | }
76 |
77 | cmd $@
78 |
--------------------------------------------------------------------------------
/scripts/lib/sh/utils.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #!/bin/sh
4 |
5 | #
6 | # Toolbox of POSIX compliant and general-purpose functions.
7 | #
8 |
9 | #
10 | # Get an option argument of a long option.
11 | # Return the number of time argc must be shifted.
12 | #
13 | getopt_longopt_arg() {
14 | if [ $# -lt 3 ]; then
15 | log_error "getopt_longopt_arg: missing arguments"
16 | return 1
17 | fi
18 |
19 | # try first the `--long-option=value` form
20 | shift=1
21 | arg="${3#*=}" # equals $3 if it does not match
22 |
23 | # or the `--long-option value` form
24 | if [ "$arg" = "$3" ]; then
25 | arg="$4"
26 | shift=2
27 | fi
28 |
29 | eval "$1=$arg"
30 | eval "$2=$shift"
31 | }
32 |
33 | #
34 | # Timestamp in Unix time.
35 | #
36 | timestamp() {
37 | date "+%s"
38 | }
39 |
40 | #
41 | # Find first set (i.e. non-empty) argument.
42 | #
43 | ffs () {
44 | while [ $# -ne 0 ]; do
45 | if [ -z "$1" ]; then
46 | shift
47 | else
48 | break
49 | fi
50 | done
51 |
52 | echo "$1"
53 | }
54 |
55 | #
56 | # Test current process is interactive.
57 | # Return 0 if current process is interface, non-zero otherwise.
58 | #
59 | process_is_interactive() {
60 | [ -t 1 ]
61 | }
62 |
63 | #
64 | # Log an error message to standard error
65 | #
66 | log_error() {
67 | echo "error:$@" >&2
68 | }
69 |
70 | #
71 | # Log a message
72 | #
73 | log_info() {
74 | echo "[+] $@"
75 | }
76 |
--------------------------------------------------------------------------------
/scripts/update-readme.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # immediately exit on any unhandled error
4 | set -e
5 |
6 | # current working directory
7 | cwd=${0%/*}
8 |
9 |
10 | #
11 | # script entry function
12 | #
13 | cmd() {
14 | gawk -i inplace \
15 | 'BEGIN { toc = 0; }
16 | // {
17 | toc = 1;
18 | print;
19 | system("gh-md-toc README.md");
20 | }
21 | // { toc = 0; }
22 | toc == 0 { print; }' \
23 | README.md
24 |
25 | sed -i \
26 | -e 's/Created by \[gh-md-toc\]/Generated by [gh-md-toc]/g' \
27 | -e "s#\(https://cdn.rawgit.com/farjump/raspberry-pi/\)feature-readme-get-started/#\1$(git rev-parse --abbrev-ref HEAD)/#g" \
28 | README.md
29 |
30 | return 0
31 | }
32 |
33 | cmd $@
34 |
--------------------------------------------------------------------------------
/sdk/Alpha.specs:
--------------------------------------------------------------------------------
1 | %rename link_gcc_c_sequence nosys_link_gcc_c_sequence
2 |
3 | *Alpha_libgloss:
4 | -lfileio -lalpha -larm
5 |
6 | *nosys_libc:
7 | %{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
8 |
9 | *link_gcc_c_sequence:
10 | %(nosys_link_gcc_c_sequence) --start-group %G %(nosys_libc) %(Alpha_libgloss) --end-group
11 |
--------------------------------------------------------------------------------
/sdk/CPU_init.c:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* This function initialise the MMU with the following mapping */
4 | /* Physical 0x00000000 - 0x20000000, virtual 0x00000000 - 0x20000000, RWX user, RWX super, write-back, no write allocate */
5 | /* RPI1 Physical 0x20000000 - 0x21000000, virtual 0x20000000 - 0x21000000, RWX user, RWX super, write-back, no-cacheable */
6 | /* RPI2&3 Physical 0x3F000000 - 0x40000000, virtual 0x20000000 - 0x21000000, RWX user, RWX super, write-back, no-cacheable */
7 | /* Physical 0x00000000 - 0x40000000, virtual 0x40000000 - 0x80000000, RWX user, RWX super, write-back, no-cacheable */
8 |
9 | /* The CPU RAM size is limited to 512 to fit almost all raspberry */
10 | /* The Whole RAM is accessible in non-cacheable mode from 0x40000000 to be able to access video RAM */
11 |
12 |
13 | #define RPI1_IO_BASE_ADDRESS 0x20000000
14 | #define RPI2_IO_BASE_ADDRESS 0x3F000000
15 | #define RPI3_IO_BASE_ADDRESS 0x3F000000
16 |
17 |
18 | /* number of 1M section in 4 GB address space */
19 | #define NB_1M_SECTION (0x100000000LL / 0x00100000)
20 | extern unsigned int CPU_init_page_table[NB_1M_SECTION];
21 |
22 | /* */
23 | #define ONE_MB (1024 * 1024)
24 | #define K_RAM_SIZE (512 *K_1M)
25 |
26 | extern unsigned int CPU_init_read_main_id();
27 | extern void CPU_init_stop_mmu();
28 | extern void CPU_init_start_mmu(unsigned int * page_table,unsigned int control_register_or_mask);
29 | extern void CPU_init_enable_vfp();
30 | extern void CPU_init_invalidate_tlb();
31 | extern void CPU_init_clean_and_invalidate_data_cache();
32 | extern void CPU_init_invalidate_instruction_cache();
33 | extern void CPU_init_disable_caches();
34 |
35 | void CPU_init_map_section(
36 | unsigned int *page_table,
37 | unsigned int virtual_address,
38 | unsigned int physical_address,
39 | unsigned int flags)
40 | {
41 | unsigned int *entry;
42 |
43 | entry = &(page_table[virtual_address >> 20]);
44 | *entry = (physical_address & 0xFFF00000) | flags | 2 |0xC00;
45 | return;
46 | }
47 |
48 |
49 |
50 | void CPU_init()
51 | {
52 | unsigned int main_id;
53 | unsigned int physical_io_address;
54 | unsigned int i;
55 |
56 | /* reading CPU id to known RPI version */
57 | main_id = CPU_init_read_main_id();
58 |
59 | /* rpi1 armv6 */
60 | if ((main_id & 0xF000) == 0xB000)
61 | {
62 | physical_io_address = RPI1_IO_BASE_ADDRESS;
63 | }
64 | /* rpi2 armv7 */
65 | else if ((main_id & 0xF000) == 0xC000)
66 | {
67 | physical_io_address = RPI2_IO_BASE_ADDRESS;
68 | }
69 | /* rpi3 armv8 */
70 | else if ((main_id & 0xF000) == 0xD000)
71 | {
72 | physical_io_address = RPI3_IO_BASE_ADDRESS;
73 | }
74 |
75 | /* clear page table */
76 | for (i = 0;i < NB_1M_SECTION; i++)
77 | {
78 | CPU_init_page_table[i] = 0;
79 | }
80 |
81 | /* map Physical 0x00000000 - 0x20000000, virtual 0x00000000 - 0x20000000, RWX user, RWX super, write-back, no write allocate */
82 | for (i = 0x00000000; i < (512 * ONE_MB); i+= ONE_MB)
83 | {
84 | CPU_init_map_section(CPU_init_page_table,i,i,0x0c); // cacheable no write allocate
85 | }
86 |
87 | /* RPI1 Physical 0x20000000 - 0x21000000, virtual 0x20000000 - 0x21000000, RWX user, RWX super, write-back, no-cacheable */
88 | /* RPI2&3 Physical 0x3F000000 - 0x40000000, virtual 0x20000000 - 0x21000000, RWX user, RWX super, write-back, no-cacheable */
89 | for (i = 0; i < (16 * ONE_MB) ; i+= ONE_MB)
90 | {
91 | CPU_init_map_section(CPU_init_page_table,RPI1_IO_BASE_ADDRESS + i,physical_io_address + i,0); // not cacheable
92 | }
93 |
94 | /* Map Physical 0x00000000 - 0x40000000, virtual 0x40000000 - 0x80000000, RWX user, RWX super, write-back, no-cacheable */
95 | for (i = 0x00000000; i < 0x40000000; i+= ONE_MB)
96 | {
97 | CPU_init_map_section(CPU_init_page_table,0x40000000 + i,i,0x0); // not cacheable
98 | }
99 |
100 | // clean_and_invalidate_data_cache();
101 | // invalidate_instruction_cache();
102 | // disable_caches();
103 | CPU_init_stop_mmu();
104 | CPU_init_invalidate_tlb();
105 | CPU_init_start_mmu((unsigned int *)((unsigned int)CPU_init_page_table),0x1005); /* ICACHE DCACHE and MMU ON */
106 | CPU_init_enable_vfp();
107 |
108 | return;
109 | }
110 |
--------------------------------------------------------------------------------
/sdk/CPU_init.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/CPU_init.o
--------------------------------------------------------------------------------
/sdk/CPU_init_util.S:
--------------------------------------------------------------------------------
1 | .text
2 |
3 | .globl CPU_init_stop_mmu
4 | .globl CPU_init_start_mmu
5 | .globl CPU_init_enable_vfp
6 | .globl CPU_init_invalidate_tlb
7 | .globl CPU_init_clean_and_invalidate_data_cache
8 | .globl CPU_init_invalidate_instruction_cache
9 | .globl CPU_init_disable_caches
10 | .globl CPU_init_read_main_id
11 |
12 |
13 | CPU_init_read_main_id:
14 | MRC p15,0,r0,c0,c0,0
15 | BX lr
16 |
17 |
18 | CPU_init_clean_and_invalidate_data_cache:
19 | // flush data cache
20 | loop:
21 | MOV r2,#0
22 | MCR p15,0,r2,c7,c10,0
23 | MRC p15,0,r2,c7,c10,6
24 | ANDS r2,r2,#01
25 | BEQ done
26 | B loop
27 | done:
28 | // invalidate data cache */
29 | MCR p15,0,r2,c7,c6,0
30 | MCR p15,0,r2,c7,c10,4
31 | BX lr
32 |
33 |
34 |
35 | CPU_init_invalidate_instruction_cache:
36 | MOV r2,#0
37 | MCR p15,0,r2,c7,c5,0
38 | MCR p15,0,r2,c7,c10,4
39 | BX lr
40 |
41 |
42 | CPU_init_disable_caches:
43 | MRC p15,0,r2,c1,c0,0
44 | BIC r2,#0x1000
45 | BIC r2,#0x0004
46 | MCR p15,0,r2,c1,c0,0
47 | BX lr
48 |
49 |
50 | CPU_init_stop_mmu:
51 | // disable mmu
52 | MRC p15,0,r2,c1,c0,0
53 | BIC r2,#0x01
54 | MCR p15,0,r2,c1,c0,0
55 | BX lr
56 |
57 | CPU_init_start_mmu:
58 | //set domain register to 0x55555555 to allow client access to perform check
59 | LDR r2,=0x55555555
60 | MCR p15,0,r2,c3,c0,0 ;@ domain
61 | // clear TTBC to enable only TTBR0
62 | MOV r2,#0
63 | MCR p15,0,r2,c2,c0,2 ;@ TTBC
64 | // set TTBR0 to pagetable address
65 | MRC p15,0,r4,c2,c0,0 ;@ tlb base
66 | MCR p15,0,r0,c2,c0,0 ;@ tlb base
67 | MCR p15,0,r0,c2,c0,1 ;@ tlb base
68 | MOV r2,#0
69 | MCR p15,0,r2,c7,c10,4
70 |
71 | // write in control register input value
72 | MRC p15,0,r2,c1,c0,0
73 | ORR r2,r2,r1
74 | MCR p15,0,r2,c1,c0,0
75 | BX lr
76 |
77 |
78 | /* enable copro single doucle precision */
79 | /* enable float */
80 | /* set fpscr to flush to zero */
81 | CPU_init_enable_vfp:
82 | //@ en@ enable the FPU
83 | MRC p15, 0, r0, c1, c0, 2
84 | ORR r0, r0, #0x300000 /* single precision */
85 | ORR r0, r0, #0xC00000 /* double precision */
86 | MCR p15, 0, r0, c1, c0, 2
87 | MOV r0, #0x40000000
88 | FMXR fpexc,r0
89 | MOV r0,#0x01000000
90 | FMXR fpscr,r0
91 | BX lr
92 |
93 |
94 | CPU_init_invalidate_tlb:
95 | MOV r2,#0
96 | MCR p15,0,r2,c8,c7,0
97 | MCR p15,0,r2,c7,c10,4
98 | BX lr
99 |
100 | .section .page_table,"a"
101 | .align 14
102 | .globl CPU_init_page_table
103 | CPU_init_page_table:
104 | .space (0x1000 * 4)
105 |
--------------------------------------------------------------------------------
/sdk/CPU_init_util.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/CPU_init_util.o
--------------------------------------------------------------------------------
/sdk/CPU_start.S:
--------------------------------------------------------------------------------
1 | .text
2 |
3 | .globl CPU_start
4 |
5 | CPU_start:
6 | /* read ARM processor implemetation id */
7 | MRC p15,0,r0,c0,c0,0
8 | MOV r1,#0x0000F000
9 | AND r1,r0,r1
10 |
11 | /* test if RPI1 */
12 | MOV r2,#0x0000B000
13 | CMP r1,r2
14 | BEQ SKIP_RPI23
15 |
16 | /* read current processsor status */
17 | /* it should be in hyp so switch supervisor */
18 | MRS r0,cpsr
19 | BIC r0,r0,#0xFF
20 | ORR r0,r0,#0xD3
21 | MSR spsr_cxsf,r0
22 | ADD r0,pc,#4
23 | .word 0xe12ef300
24 | // MSR ELR_hyp,r0 , this register is not know when ARMv6 compiling
25 | .word 0xe160006e
26 | //ERET this instruction is not know when Armv6 compiling
27 |
28 | SKIP_RPI23:
29 | LDR sp, =__stack
30 | SUB sp,sp,#64
31 | BL CPU_init
32 | B _start
33 |
--------------------------------------------------------------------------------
/sdk/CPU_start.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/CPU_start.o
--------------------------------------------------------------------------------
/sdk/Dockerfile:
--------------------------------------------------------------------------------
1 | # Development container base image
2 |
3 | FROM debian:stretch
4 |
5 | RUN apt-get -q update
6 |
7 | # lang settings
8 | RUN apt-get -q install -y --no-install-recommends locales && locale-gen C.UTF-8
9 | ENV LANG C.UTF-8
10 | ENV LC_ALL C.UTF-8
11 |
12 | # Dependencies:
13 | # sudo: for privileged execution
14 | # curl: used to download files
15 | # bzip2: tarball uncompression
16 | # ca-certificates: HTTPS downloads
17 | RUN apt-get update && apt-get install --no-install-recommends -y \
18 | sudo \
19 | bzip2 \
20 | curl \
21 | make \
22 | libncurses5 \
23 | gawk \
24 | git \
25 | ca-certificates
26 |
27 | # Official distribution of the ARM Toolchain
28 | COPY ./scripts/ /tmp/scripts/
29 | RUN /tmp/scripts/install-toolchain.sh --prefix=/opt/arm-none-eabi
30 | ENV PATH="/opt/arm-none-eabi/bin:$PATH"
31 |
32 | # Helper script to generate the markdown Table of Content
33 | RUN curl -sSL https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc > /usr/local/bin/gh-md-toc \
34 | && chmod +x /usr/local/bin/gh-md-toc
35 |
36 | # Create a non-root user with the same uid as on the host to allow proper file
37 | # permissions created inside the container. Since it is not root, allow calling
38 | # sudo without password when required.
39 | ARG uid
40 | RUN useradd -m --uid $uid --user-group user \
41 | && echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/user \
42 | && chmod a=r,o= /etc/sudoers.d/user
43 | USER user
44 |
45 | # man bash explains SIGTERM is ignored and that SIGHUP
46 | # stops and dispatches the signal to running childs
47 | STOPSIGNAL SIGHUP
48 |
--------------------------------------------------------------------------------
/sdk/Makefile:
--------------------------------------------------------------------------------
1 | GNU = arm-none-eabi
2 | CFLAGS = -mfloat-abi=hard -mfpu=vfp -march=armv6zk -mtune=arm1176jzf-s -Og -g
3 |
4 | all : libCPU.a
5 |
6 | libCPU.a : CPU_start.o CPU_init.o CPU_init_util.o
7 | $(GNU)-ar -r libCPU.a CPU_init.o CPU_init_util.o
8 |
9 | %.o: %.c
10 | $(GNU)-gcc $(CFLAGS) $^ -c
11 |
12 | %.o: %.S
13 | $(GNU)-gcc $(CFLAGS) $^ -c
14 |
15 |
16 | clean :
17 | rm *.o libCPU.a
18 |
19 |
20 |
--------------------------------------------------------------------------------
/sdk/alpha.gdb:
--------------------------------------------------------------------------------
1 | # Full set of registers as sent by Alpha
2 | set tdesc filename sdk/armv6-core.xml
3 |
4 | # Maximum exchange size of large packets
5 | set remote memory-read-packet-size 1024
6 | set remote memory-write-packet-size 1024
7 |
8 | #
9 | # Macro to make current function call back Alpha to restore its exception table.
10 | # The macro replaces current function's return address (LR) with a program
11 | # written at 0x2000 which calls Alpha and then returns to the actual current
12 | # function's caller.
13 | #
14 | # Usage:
15 | # ```
16 | # tbreak *MY_EXCEPTION_TABLE_INIT_FUNCTION
17 | # command
18 | # alpha_hook_write_restore_exception_table
19 | # continue
20 | # end
21 | # ```
22 | # Note the use of GDB notation `*function` to set a breakpoint at the exact
23 | # entry address of `function`, before its prolog, because the macro must be used at
24 | # the exact entry point of the function that needs to be hooked.
25 | #
26 | define alpha_hook_write_restore_exception_table
27 | set $freemem = (unsigned int*) 0x2000
28 | set $alpha_callback = (unsigned int) 0x07f09200
29 |
30 | # save the return address to the caller
31 | set *$freemem = $lr
32 | set $freemem += 1
33 | # save the callback address
34 | set *$freemem = $alpha_callback
35 | set $freemem += 3
36 |
37 | # Set the return address to current freemem's address to return to it when
38 | # returning from current function. This is where the program will now be
39 | # written.
40 | set $lr = $freemem
41 |
42 | # Write the following program:
43 | # 0x2010: str r0, [pc, #-16] ; 0x2008
44 | # 0x2014: str r1, [pc, #-16] ; 0x200c
45 | # 0x2018: ldr r2, [pc, #-28] ; 0x2004
46 | # 0x201c: blx r2
47 | # 0x2020: ldr r0, [pc, #-32] ; 0x2008
48 | # 0x2024: ldr r1, [pc, #-32] ; 0x200c
49 | # 0x2028: ldr r2, [pc, #-48] ; 0x2000
50 | # 0x202c: bx r2
51 | #
52 | set *$freemem = 0xe50f0010
53 | set $freemem += 1
54 | set *$freemem = 0xe50f1010
55 | set $freemem += 1
56 | set *$freemem = 0xe51f201c
57 | set $freemem += 1
58 | set *$freemem = 0xe12fff32
59 | set $freemem += 1
60 | set *$freemem = 0xe51f0020
61 | set $freemem += 1
62 | set *$freemem = 0xe51f1020
63 | set $freemem += 1
64 | set *$freemem = 0xe51f2030
65 | set $freemem += 1
66 | set *$freemem = 0xe12fff12
67 | set $freemem += 1
68 | end
69 |
--------------------------------------------------------------------------------
/sdk/armv6-core.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/sdk/libalpha.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/libalpha.a
--------------------------------------------------------------------------------
/sdk/libalpha/include/alpha/fileio.h:
--------------------------------------------------------------------------------
1 | //
2 | // This file is subject to the terms and conditions defined in
3 | // file 'LICENSE', which is part of this source code package.
4 | //
5 |
6 | #ifndef LIBALPHA_FILEIO_H_
7 | # define LIBALPHA_FILEIO_H_
8 |
9 | # ifdef __cplusplus
10 | extern "C" {
11 | # endif
12 |
13 | # include
14 |
15 | extern void FILEIO_OPEN (/* in */ const char* path,
16 | /* in */ fio_uint32_t flags,
17 | /* in */ fio_uint32_t mode,
18 | /* out */ fio_uint32_t* errno,
19 | /* out */ fio_int32_t* return_code);
20 |
21 | extern void FILEIO_CLOSE (/* in */ fio_int32_t fd,
22 | /* out */ fio_uint32_t* errno,
23 | /* out */ fio_int32_t* return_code);
24 |
25 | extern void FILEIO_READ (/* in */ fio_int32_t fd,
26 | /* in */ void* dst,
27 | /* in */ fio_uint32_t count,
28 | /* out */ fio_uint32_t* errno,
29 | /* out */ fio_int32_t* return_code);
30 |
31 | extern void FILEIO_WRITE (/* in */ fio_int32_t fd,
32 | /* in */ const void* src,
33 | /* in */ fio_uint32_t count,
34 | /* out */ fio_uint32_t* errno,
35 | /* out */ fio_int32_t* return_code);
36 |
37 | extern void FILEIO_LSEEK (/* in */ fio_int32_t fd,
38 | /* in */ fio_int32_t offset,
39 | /* in */ fio_uint32_t flag,
40 | /* out */ fio_uint32_t* errno,
41 | /* out */ fio_int32_t* return_code);
42 |
43 | extern void FILEIO_RENAME (/* in */ const char* old_name,
44 | /* in */ const char* new_name,
45 | /* out */ fio_uint32_t* errno,
46 | /* out */ fio_int32_t* return_code);
47 |
48 | extern void FILEIO_UNLINK (/* in */ const char* path,
49 | /* out */ fio_uint32_t* errno,
50 | /* out */ fio_int32_t* return_code);
51 |
52 | extern void FILEIO_STAT (/* in */ const char* path,
53 | /* in */ struct fio_stat* stat,
54 | /* out */ fio_uint32_t* errno,
55 | /* out */ fio_int32_t* return_code);
56 |
57 | extern void FILEIO_FSTAT (/* in */ fio_int32_t fd,
58 | /* in */ struct fio_stat* stat,
59 | /* out */ fio_uint32_t* errno,
60 | /* out */ fio_int32_t* return_code);
61 |
62 | extern void FILEIO_GETTIMEOFDAY (/* in */ struct fio_timeval* timeval,
63 | /* in */ void* timezone,
64 | /* out */ fio_uint32_t* errno,
65 | /* out */ fio_int32_t* return_code);
66 |
67 | extern void FILEIO_ISATTY (/* in */ fio_int32_t fd,
68 | /* out */ fio_uint32_t* errno,
69 | /* out */ fio_int32_t* return_code);
70 |
71 | extern void FILEIO_SYSTEM (/* in */ const char* command,
72 | /* out */ fio_uint32_t* errno,
73 | /* out */ fio_int32_t* return_code);
74 |
75 | # ifdef __cplusplus
76 | }
77 | # endif
78 |
79 | #endif /* !LIBALPHA_FILEIO_H_ */
80 |
--------------------------------------------------------------------------------
/sdk/libalpha/include/gdb/fileio.h:
--------------------------------------------------------------------------------
1 | /* Hosted File I/O interface definitions, for GDB, the GNU Debugger.
2 |
3 | Copyright (C) 2003-2018 Free Software Foundation, Inc.
4 |
5 | This program is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation; either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see . */
17 |
18 | #ifndef GDB_FILEIO_H_
19 | #define GDB_FILEIO_H_
20 |
21 | /* The following flags are defined to be independent of the host
22 | as well as the target side implementation of these constants.
23 | All constants are defined with a leading FILEIO_ in the name
24 | to allow the usage of these constants together with the
25 | corresponding implementation dependent constants in one module. */
26 |
27 | /* open(2) flags */
28 | #define FILEIO_O_RDONLY 0x0
29 | #define FILEIO_O_WRONLY 0x1
30 | #define FILEIO_O_RDWR 0x2
31 | #define FILEIO_O_APPEND 0x8
32 | #define FILEIO_O_CREAT 0x200
33 | #define FILEIO_O_TRUNC 0x400
34 | #define FILEIO_O_EXCL 0x800
35 | #define FILEIO_O_SUPPORTED (FILEIO_O_RDONLY | FILEIO_O_WRONLY| \
36 | FILEIO_O_RDWR | FILEIO_O_APPEND| \
37 | FILEIO_O_CREAT | FILEIO_O_TRUNC| \
38 | FILEIO_O_EXCL)
39 |
40 | /* mode_t bits */
41 | #define FILEIO_S_IFREG 0100000
42 | #define FILEIO_S_IFDIR 040000
43 | #define FILEIO_S_IFCHR 020000
44 | #define FILEIO_S_IRUSR 0400
45 | #define FILEIO_S_IWUSR 0200
46 | #define FILEIO_S_IXUSR 0100
47 | #define FILEIO_S_IRWXU 0700
48 | #define FILEIO_S_IRGRP 040
49 | #define FILEIO_S_IWGRP 020
50 | #define FILEIO_S_IXGRP 010
51 | #define FILEIO_S_IRWXG 070
52 | #define FILEIO_S_IROTH 04
53 | #define FILEIO_S_IWOTH 02
54 | #define FILEIO_S_IXOTH 01
55 | #define FILEIO_S_IRWXO 07
56 | #define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \
57 | FILEIO_S_IRWXU|FILEIO_S_IRWXG| \
58 | FILEIO_S_IRWXO)
59 |
60 | /* lseek(2) flags */
61 | #define FILEIO_SEEK_SET 0
62 | #define FILEIO_SEEK_CUR 1
63 | #define FILEIO_SEEK_END 2
64 |
65 | /* errno values */
66 | #define FILEIO_EPERM 1
67 | #define FILEIO_ENOENT 2
68 | #define FILEIO_EINTR 4
69 | #define FILEIO_EIO 5
70 | #define FILEIO_EBADF 9
71 | #define FILEIO_EACCES 13
72 | #define FILEIO_EFAULT 14
73 | #define FILEIO_EBUSY 16
74 | #define FILEIO_EEXIST 17
75 | #define FILEIO_ENODEV 19
76 | #define FILEIO_ENOTDIR 20
77 | #define FILEIO_EISDIR 21
78 | #define FILEIO_EINVAL 22
79 | #define FILEIO_ENFILE 23
80 | #define FILEIO_EMFILE 24
81 | #define FILEIO_EFBIG 27
82 | #define FILEIO_ENOSPC 28
83 | #define FILEIO_ESPIPE 29
84 | #define FILEIO_EROFS 30
85 | #define FILEIO_ENOSYS 88
86 | #define FILEIO_ENAMETOOLONG 91
87 | #define FILEIO_EUNKNOWN 9999
88 |
89 | /* limits */
90 | #define FILEIO_INT_MIN -2147483648L
91 | #define FILEIO_INT_MAX 2147483647L
92 | #define FILEIO_UINT_MAX 4294967295UL
93 | #define FILEIO_LONG_MIN -9223372036854775808LL
94 | #define FILEIO_LONG_MAX 9223372036854775807LL
95 | #define FILEIO_ULONG_MAX 18446744073709551615ULL
96 |
97 | /* Integral types as used in protocol. */
98 | typedef __INT32_TYPE__ fio_int32_t;
99 | typedef __UINT32_TYPE__ fio_uint32_t, fio_mode_t, fio_time_t;
100 | typedef __INT64_TYPE__ fio_int64_t;
101 | typedef __UINT64_TYPE__ fio_uint64_t;
102 |
103 | /* Struct stat as used in protocol. */
104 | struct fio_stat {
105 | fio_uint32_t fst_dev;
106 | fio_uint32_t fst_ino;
107 | fio_mode_t fst_mode;
108 | fio_uint32_t fst_nlink;
109 | fio_uint32_t fst_uid;
110 | fio_uint32_t fst_gid;
111 | fio_uint32_t fst_rdev;
112 | fio_uint64_t fst_size;
113 | fio_uint64_t fst_blksize;
114 | fio_uint64_t fst_blocks;
115 | fio_time_t fst_atime;
116 | fio_time_t fst_mtime;
117 | fio_time_t fst_ctime;
118 | };
119 |
120 | /* Struct timeval as used in protocol. */
121 | struct fio_timeval {
122 | fio_time_t ftv_sec;
123 | fio_int64_t ftv_usec;
124 | };
125 |
126 | #endif /* GDB_FILEIO_H_ */
127 |
--------------------------------------------------------------------------------
/sdk/libarm.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/libarm.a
--------------------------------------------------------------------------------
/sdk/libfileio.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/farjump/raspberry-pi/c998d8316abf13573675547d0b05c1b994cf4a74/sdk/libfileio.a
--------------------------------------------------------------------------------
/sdk/libfileio/src/close.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int close(int fd)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_CLOSE(fd, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/errno.h:
--------------------------------------------------------------------------------
1 | #ifndef FILEIO_ERRNO_H_
2 | # define FILEIO_ERRNO_H_
3 |
4 | extern int errno;
5 |
6 | #endif /* !FILEIO_ERRNO_H_ */
7 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/exit.c:
--------------------------------------------------------------------------------
1 | #define X_ASM_OPCODE(OPCODE) ASM_OPCODE(OPCODE)
2 | #define ASM_OPCODE(OPCODE) \
3 | asm(" .int " #OPCODE "\n");
4 |
5 | void _exit(int rc)
6 | {
7 | (void) rc;
8 | X_ASM_OPCODE( K_GDB_BREAKPOINT_TRAP );
9 | while (1);
10 | }
11 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/fstat.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int fstat(int fd, struct stat *st)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_FSTAT(fd, (t_fileio_stat*) st, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/gettimeofday.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int gettimeofday(struct timeval* tv, void* tz)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | (void) tz; // not implemented
10 | FILEIO_GETTIMEOFDAY((t_fileio_timeval*) tv, FILEIO_NULL, &errnum, &rc);
11 |
12 | if (rc == -1) {
13 | errno = errnum;
14 | }
15 | return rc;
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/isatty.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int isatty(int fd)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_ISATTY(fd, &errnum, &rc);
10 |
11 | if (rc == 0) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/lseek.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int lseek(int fd, int offset, int dir)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_LSEEK(fd, offset, dir, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/open.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int open(char* file, int flags, int mode)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_OPEN((t_fileio_uchar*) file, flags, mode, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/read.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int read(int fd, char *buf, int count)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_READ(fd, (t_fileio_uchar*) buf, count, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/stat.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int stat(const char* file, struct stat* st)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_STAT((t_fileio_uchar*) file, (t_fileio_stat*) st, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/unlink.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int unlink(char *name)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_UNLINK((t_fileio_uchar*) name, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/libfileio/src/write.c:
--------------------------------------------------------------------------------
1 | #include "alpha/fileio.h"
2 | #include "errno.h"
3 |
4 | int write(int fd, char* buf, int count)
5 | {
6 | t_fileio_errno errnum;
7 | t_fileio_int32 rc;
8 |
9 | FILEIO_WRITE(fd, (t_fileio_uchar*) buf, count, &errnum, &rc);
10 |
11 | if (rc == -1) {
12 | errno = errnum;
13 | }
14 | return rc;
15 | }
16 |
--------------------------------------------------------------------------------
/sdk/link.ld:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Free Software Foundation, Inc.
2 | Copying and distribution of this script, with or without modification,
3 | are permitted in any medium without royalty provided the copyright
4 | notice and this notice are preserved. */
5 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
6 | OUTPUT_ARCH(arm)
7 | ENTRY(_start)
8 |
9 | SECTIONS
10 | {
11 | /* Read-only sections, merged into text segment: */
12 | PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
13 | .entry : { CPU_start.o }
14 | .text : { *(.text*) }
15 | .interp : { *(.interp) }
16 | .note.gnu.build-id : { *(.note.gnu.build-id) }
17 | .hash : { *(.hash) }
18 | .gnu.hash : { *(.gnu.hash) }
19 | .dynsym : { *(.dynsym) }
20 | .dynstr : { *(.dynstr) }
21 | .gnu.version : { *(.gnu.version) }
22 | .gnu.version_d : { *(.gnu.version_d) }
23 | .gnu.version_r : { *(.gnu.version_r) }
24 | .rel.dyn :
25 | {
26 | *(.rel.init)
27 | *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
28 | *(.rel.fini)
29 | *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
30 | *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)
31 | *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
32 | *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
33 | *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
34 | *(.rel.ctors)
35 | *(.rel.dtors)
36 | *(.rel.got)
37 | *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
38 | PROVIDE_HIDDEN (__rel_iplt_start = .);
39 | *(.rel.iplt)
40 | PROVIDE_HIDDEN (__rel_iplt_end = .);
41 | }
42 | .rela.dyn :
43 | {
44 | *(.rela.init)
45 | *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
46 | *(.rela.fini)
47 | *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
48 | *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
49 | *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
50 | *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
51 | *(.rela.ctors)
52 | *(.rela.dtors)
53 | *(.rela.got)
54 | *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
55 | PROVIDE_HIDDEN (__rela_iplt_start = .);
56 | *(.rela.iplt)
57 | PROVIDE_HIDDEN (__rela_iplt_end = .);
58 | }
59 | .rel.plt :
60 | {
61 | *(.rel.plt)
62 | }
63 | .rela.plt :
64 | {
65 | *(.rela.plt)
66 | }
67 | .init :
68 | {
69 | KEEP (*(SORT_NONE(.init)))
70 | }
71 | .plt : { *(.plt) }
72 | .iplt : { *(.iplt) }
73 | .fini :
74 | {
75 | KEEP (*(SORT_NONE(.fini)))
76 | }
77 | PROVIDE (__etext = .);
78 | PROVIDE (_etext = .);
79 | PROVIDE (etext = .);
80 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
81 | .rodata1 : { *(.rodata1) }
82 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
83 | PROVIDE_HIDDEN (__exidx_start = .);
84 | .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
85 | PROVIDE_HIDDEN (__exidx_end = .);
86 | .eh_frame_hdr : { *(.eh_frame_hdr) }
87 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
88 | .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
89 | .gcc_except_table.*) }
90 | /* These sections are generated by the Sun/Oracle C++ compiler. */
91 | .exception_ranges : ONLY_IF_RO { *(.exception_ranges
92 | .exception_ranges*) }
93 | /* Adjust the address for the data segment. We want to adjust up to
94 | the same address within the page on the next page up. */
95 | . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));
96 | /* Exception handling */
97 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
98 | .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
99 | .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
100 | /* Thread Local Storage sections */
101 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
102 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
103 | .preinit_array :
104 | {
105 | PROVIDE_HIDDEN (__preinit_array_start = .);
106 | KEEP (*(.preinit_array))
107 | PROVIDE_HIDDEN (__preinit_array_end = .);
108 | }
109 | .init_array :
110 | {
111 | PROVIDE_HIDDEN (__init_array_start = .);
112 | KEEP (*(SORT(.init_array.*)))
113 | KEEP (*(.init_array ))
114 | PROVIDE_HIDDEN (__init_array_end = .);
115 | }
116 | .fini_array :
117 | {
118 | PROVIDE_HIDDEN (__fini_array_start = .);
119 | KEEP (*(SORT(.fini_array.*)))
120 | KEEP (*(.fini_array ))
121 | PROVIDE_HIDDEN (__fini_array_end = .);
122 | }
123 | .ctors :
124 | {
125 | /* gcc uses crtbegin.o to find the start of
126 | the constructors, so we make sure it is
127 | first. Because this is a wildcard, it
128 | doesn't matter if the user does not
129 | actually link against crtbegin.o; the
130 | linker won't look for a file to match a
131 | wildcard. The wildcard also means that it
132 | doesn't matter which directory crtbegin.o
133 | is in. */
134 | KEEP (*crtbegin.o(.ctors))
135 | KEEP (*crtbegin?.o(.ctors))
136 | /* We don't want to include the .ctor section from
137 | the crtend.o file until after the sorted ctors.
138 | The .ctor section from the crtend file contains the
139 | end of ctors marker and it must be last */
140 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
141 | KEEP (*(SORT(.ctors.*)))
142 | KEEP (*(.ctors))
143 | }
144 | .dtors :
145 | {
146 | KEEP (*crtbegin.o(.dtors))
147 | KEEP (*crtbegin?.o(.dtors))
148 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
149 | KEEP (*(SORT(.dtors.*)))
150 | KEEP (*(.dtors))
151 | }
152 | .jcr : { KEEP (*(.jcr)) }
153 | .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
154 | .dynamic : { *(.dynamic) }
155 | .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
156 | .data :
157 | {
158 | __data_start = . ;
159 | *(.data .data.* .gnu.linkonce.d.*)
160 | SORT(CONSTRUCTORS)
161 | }
162 | .data1 : { *(.data1) }
163 | _edata = .; PROVIDE (edata = .);
164 | . = .;
165 | __bss_start = .;
166 | __bss_start__ = .;
167 | .bss :
168 | {
169 | *(.dynbss)
170 | *(.bss .bss.* .gnu.linkonce.b.*)
171 | *(COMMON)
172 | /* Align here to ensure that the .bss section occupies space up to
173 | _end. Align after .bss to ensure correct alignment even if the
174 | .bss section disappears because there are no input sections.
175 | FIXME: Why do we need it? When there is no .bss section, we don't
176 | pad the .data section. */
177 | . = ALIGN(. != 0 ? 32 / 8 : 1);
178 | }
179 | _bss_end__ = . ; __bss_end__ = . ;
180 | . = ALIGN(32 / 8);
181 | . = SEGMENT_START("ldata-segment", .);
182 | . = ALIGN(32 / 8);
183 | __end__ = . ;
184 | _end = .; PROVIDE (end = .);
185 |
186 | . = 0x07EFC000;
187 | .page_table (NOLOAD) : { *(.page_table) }
188 |
189 |
190 |
191 | /* Stabs debugging sections. */
192 | .stab 0 : { *(.stab) }
193 | .stabstr 0 : { *(.stabstr) }
194 | .stab.excl 0 : { *(.stab.excl) }
195 | .stab.exclstr 0 : { *(.stab.exclstr) }
196 | .stab.index 0 : { *(.stab.index) }
197 | .stab.indexstr 0 : { *(.stab.indexstr) }
198 | .comment 0 : { *(.comment) }
199 | /* DWARF debug sections.
200 | Symbols in the DWARF debugging sections are relative to the beginning
201 | of the section so we begin them at 0. */
202 | /* DWARF 1 */
203 | .debug 0 : { *(.debug) }
204 | .line 0 : { *(.line) }
205 | /* GNU DWARF 1 extensions */
206 | .debug_srcinfo 0 : { *(.debug_srcinfo) }
207 | .debug_sfnames 0 : { *(.debug_sfnames) }
208 | /* DWARF 1.1 and DWARF 2 */
209 | .debug_aranges 0 : { *(.debug_aranges) }
210 | .debug_pubnames 0 : { *(.debug_pubnames) }
211 | /* DWARF 2 */
212 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
213 | .debug_abbrev 0 : { *(.debug_abbrev) }
214 | .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
215 | .debug_frame 0 : { *(.debug_frame) }
216 | .debug_str 0 : { *(.debug_str) }
217 | .debug_loc 0 : { *(.debug_loc) }
218 | .debug_macinfo 0 : { *(.debug_macinfo) }
219 | /* SGI/MIPS DWARF 2 extensions */
220 | .debug_weaknames 0 : { *(.debug_weaknames) }
221 | .debug_funcnames 0 : { *(.debug_funcnames) }
222 | .debug_typenames 0 : { *(.debug_typenames) }
223 | .debug_varnames 0 : { *(.debug_varnames) }
224 | /* DWARF 3 */
225 | .debug_pubtypes 0 : { *(.debug_pubtypes) }
226 | .debug_ranges 0 : { *(.debug_ranges) }
227 | /* DWARF Extension. */
228 | .debug_macro 0 : { *(.debug_macro) }
229 | .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
230 | .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
231 | /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
232 | }
233 |
234 |
235 | __stack = 0x07EFBF00;
236 |
--------------------------------------------------------------------------------
/src/hello-world/HelloWorld.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(void)
5 | {
6 | // String prompt and show the terminal cursor
7 | printf("Enter a string: \e[?25h");
8 | fflush(stdout);
9 |
10 | // Read a string
11 | char buffer[20];
12 | if (scanf("%19s", &buffer) == 1)
13 | {
14 | // Say Hi
15 | printf("RPi says \"Hello %s!\"\n", buffer);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/raytracer/Raytracing.c:
--------------------------------------------------------------------------------
1 | #include "Raytracing.h"
2 | #include
3 | #include
4 | #include "VC.h"
5 |
6 | T_RAYT_WORLD *P_RAYT_WORLD;
7 |
8 | void RAYT_GET_3D(
9 | T_RAYT_RAY *P_RAY,
10 | T_FLOAT F_PARAMETER,
11 | T_3D *P_3D)
12 | {
13 | P_3D->F_X = P_RAY->S_ORIGIN.F_X + P_RAY->S_VECTOR.F_X * F_PARAMETER;// - 0.1;
14 | P_3D->F_Y = P_RAY->S_ORIGIN.F_Y + P_RAY->S_VECTOR.F_Y * F_PARAMETER;// - 0.1;
15 | P_3D->F_Z = P_RAY->S_ORIGIN.F_Z + P_RAY->S_VECTOR.F_Z * F_PARAMETER;// - 0.1;
16 |
17 | return;
18 | }
19 |
20 |
21 | void RAYT_GET_FIRST_INTERSECTION_WITH_SPHERE(
22 | T_RAYT_RAY *P_RAY,
23 | T_RAYT_SPHERE *P_SPHERE,
24 | T_UINT32 *P_NB_INTERSECTION,
25 | T_FLOAT *P_INTERSECTION_PARAM,
26 | T_3D *P_INTERSECTION,
27 | T_3D *P_NORMAL_VECTOR,
28 | T_RAYT_PROPERTY **P_PROPERTY)
29 | {
30 | T_FLOAT A,B,C;
31 | T_3D S_VECTOR;
32 | T_FLOAT F_DESCRIMINANT;
33 | T_FLOAT F_INTERSECTION;
34 | T_FLOAT F_INTERSECTION0;
35 | T_FLOAT F_INTERSECTION1;
36 | T_UINT32 I_NB_INTERSECTION;
37 | T_3D S_INTERSECTION;
38 |
39 | S_VECTOR = P_RAY->S_VECTOR;
40 | A = 1.0; /*because RAY vector is normalized */
41 | B = 2.0 * ( P_RAY->S_VECTOR.F_X *(P_RAY->S_ORIGIN.F_X - P_SPHERE->S_ORIGIN.F_X) +
42 | P_RAY->S_VECTOR.F_Y *(P_RAY->S_ORIGIN.F_Y - P_SPHERE->S_ORIGIN.F_Y) +
43 | P_RAY->S_VECTOR.F_Z *(P_RAY->S_ORIGIN.F_Z - P_SPHERE->S_ORIGIN.F_Z) );
44 | C =( (P_RAY->S_ORIGIN.F_X - P_SPHERE->S_ORIGIN.F_X) * (P_RAY->S_ORIGIN.F_X - P_SPHERE->S_ORIGIN.F_X) +
45 | (P_RAY->S_ORIGIN.F_Y - P_SPHERE->S_ORIGIN.F_Y) * (P_RAY->S_ORIGIN.F_Y - P_SPHERE->S_ORIGIN.F_Y) +
46 | (P_RAY->S_ORIGIN.F_Z - P_SPHERE->S_ORIGIN.F_Z) * (P_RAY->S_ORIGIN.F_Z - P_SPHERE->S_ORIGIN.F_Z) -
47 | (P_SPHERE->F_RADIUS * P_SPHERE->F_RADIUS) );
48 |
49 | F_DESCRIMINANT = B*B - 4.0*A*C;
50 | *P_PROPERTY = &(P_SPHERE->S_PROPERTY);
51 |
52 | I_NB_INTERSECTION = 0;
53 | F_INTERSECTION = 0;
54 |
55 | if (F_DESCRIMINANT < 0.0)
56 | {
57 | I_NB_INTERSECTION = 0;
58 | }
59 | else if (F_DESCRIMINANT == 0.0)
60 | {
61 | F_INTERSECTION = -B / 2.0;
62 |
63 | if (F_INTERSECTION < 0.0)
64 | {
65 | I_NB_INTERSECTION = 0;
66 | }
67 | else
68 | {
69 | I_NB_INTERSECTION = 1;
70 | }
71 | }
72 | else if (F_DESCRIMINANT > 0.0)
73 | {
74 | F_INTERSECTION0 = (-B - sqrt(F_DESCRIMINANT) ) / 2.0;
75 | F_INTERSECTION1 = (-B + sqrt(F_DESCRIMINANT) ) / 2.0;
76 | if ( (F_INTERSECTION0 < 0.0) && (F_INTERSECTION1 < 0.0))
77 | {
78 | I_NB_INTERSECTION = 0;
79 | }
80 | else if ( (F_INTERSECTION0 < 0.0) && (F_INTERSECTION1 >= 0.0))
81 | {
82 | I_NB_INTERSECTION = 1;
83 | F_INTERSECTION = F_INTERSECTION1;
84 | }
85 | else if ( (F_INTERSECTION0 >= 0.0) && (F_INTERSECTION1 < 0.0))
86 | {
87 | I_NB_INTERSECTION = 1;
88 | F_INTERSECTION = F_INTERSECTION0;
89 |
90 | }
91 | else if ( (F_INTERSECTION0 >= 0.0) && (F_INTERSECTION1 >= 0.0))
92 | {
93 | I_NB_INTERSECTION = 1;
94 | if (F_INTERSECTION0 < F_INTERSECTION1)
95 | {
96 | F_INTERSECTION = F_INTERSECTION0;
97 | }
98 | else
99 | {
100 | F_INTERSECTION = F_INTERSECTION1;
101 | }
102 | }
103 | }
104 |
105 | *P_NB_INTERSECTION = I_NB_INTERSECTION;
106 | *P_INTERSECTION_PARAM = F_INTERSECTION;
107 |
108 | if (I_NB_INTERSECTION != 0)
109 | {
110 | RAYT_GET_3D(P_RAY,F_INTERSECTION,&S_INTERSECTION);
111 | S_VECTOR.F_X = S_INTERSECTION.F_X - P_SPHERE->S_ORIGIN.F_X;
112 | S_VECTOR.F_Y = S_INTERSECTION.F_Y - P_SPHERE->S_ORIGIN.F_Y;
113 | S_VECTOR.F_Z = S_INTERSECTION.F_Z - P_SPHERE->S_ORIGIN.F_Z;
114 | RAYT_NORMALIZE_VECTOR(S_VECTOR,P_NORMAL_VECTOR);
115 | *P_INTERSECTION = S_INTERSECTION;
116 | }
117 | return;
118 | }
119 |
120 |
121 | void RAYT_GET_PRIMARY_RAY(
122 | T_UINT32 I_HORIZONTAL_PIXEL,
123 | T_UINT32 I_VERTICAL_PIXEL,
124 | T_UINT32 I_NB_HORIZONTAL_PIXEL,
125 | T_UINT32 I_NB_VERTICAL_PIXEL,
126 | T_RAYT_RAY *P_RAY)
127 | {
128 | T_3D S_VECTOR,S_NORMALIZED_VECTOR;
129 | T_RAYT_WINDOW * P_WINDOW;
130 |
131 | P_RAY->S_ORIGIN = P_RAYT_WORLD->S_EYE;
132 |
133 | P_WINDOW = &(P_RAYT_WORLD->S_WINDOW);
134 | S_VECTOR.F_X = P_WINDOW->S_ORIGIN.F_X +
135 | ( (I_HORIZONTAL_PIXEL * (P_WINDOW->S_HORIZONTAL_VECTOR.F_X)) / (I_NB_HORIZONTAL_PIXEL - 1)) +
136 | ( (I_VERTICAL_PIXEL * (P_WINDOW->S_VERTICAL_VECTOR.F_X)) / (I_NB_VERTICAL_PIXEL - 1)) -
137 | P_RAYT_WORLD->S_EYE.F_X;
138 | S_VECTOR.F_Y = P_WINDOW->S_ORIGIN.F_Y +
139 | ( (I_HORIZONTAL_PIXEL * (P_WINDOW->S_HORIZONTAL_VECTOR.F_Y)) / (I_NB_HORIZONTAL_PIXEL - 1)) +
140 | ( (I_VERTICAL_PIXEL * (P_WINDOW->S_VERTICAL_VECTOR.F_Y)) / (I_NB_VERTICAL_PIXEL - 1)) -
141 | P_RAYT_WORLD->S_EYE.F_Y;
142 | S_VECTOR.F_Z = P_WINDOW->S_ORIGIN.F_Z +
143 | ( (I_HORIZONTAL_PIXEL * (P_WINDOW->S_HORIZONTAL_VECTOR.F_Z)) / (I_NB_HORIZONTAL_PIXEL - 1)) +
144 | ( (I_VERTICAL_PIXEL * (P_WINDOW->S_VERTICAL_VECTOR.F_Z)) / (I_NB_VERTICAL_PIXEL - 1)) -
145 | P_RAYT_WORLD->S_EYE.F_Z;
146 |
147 | RAYT_NORMALIZE_VECTOR(S_VECTOR,&S_NORMALIZED_VECTOR);
148 | P_RAY->S_VECTOR = S_NORMALIZED_VECTOR;
149 | return;
150 | }
151 |
152 | void RAYT_GET_RGB_FROM_LIGHT(
153 | T_PTR P_OBJECT,
154 | T_3D *P_ORIGIN,
155 | T_RAYT_LIGHT *P_LIGHT,
156 | T_3D *P_VECTOR,
157 | T_RAYT_RGB *P_RGB)
158 | {
159 |
160 | T_RAYT_RAY S_RAY;
161 | T_3D S_VECTOR;
162 | T_BOOLEAN B_INTERSECTION;
163 | T_UINT32 I_INDEX;
164 | T_UINT32 I_TMP_NB_INTERSECTION;
165 | T_FLOAT F_TMP_INTERSECTION;
166 | T_3D S_TMP_INTERSECTION;
167 | T_3D S_TMP_VECTOR;
168 | T_RAYT_PROPERTY *P_TMP_PROPERTY;
169 |
170 |
171 | S_RAY.S_ORIGIN = *P_ORIGIN;
172 | S_VECTOR.F_X = P_LIGHT->S_ORIGIN.F_X - P_ORIGIN->F_X;
173 | S_VECTOR.F_Y = P_LIGHT->S_ORIGIN.F_Y - P_ORIGIN->F_Y;
174 | S_VECTOR.F_Z = P_LIGHT->S_ORIGIN.F_Z - P_ORIGIN->F_Z;
175 | RAYT_NORMALIZE_VECTOR(S_VECTOR,&(S_RAY.S_VECTOR));
176 |
177 | *P_VECTOR = S_RAY.S_VECTOR;
178 |
179 | B_INTERSECTION = K_FALSE;
180 |
181 | for (I_INDEX = 0; (I_INDEX < P_RAYT_WORLD->I_NB_SPHERE) && (B_INTERSECTION == K_FALSE) ; I_INDEX ++)
182 | {
183 | if (P_OBJECT != &(P_RAYT_WORLD->P_SPHERE[I_INDEX]))
184 | {
185 | RAYT_GET_FIRST_INTERSECTION_WITH_SPHERE(&S_RAY,
186 | &(P_RAYT_WORLD->P_SPHERE[I_INDEX]),
187 | &I_TMP_NB_INTERSECTION,
188 | &F_TMP_INTERSECTION,
189 | &S_TMP_INTERSECTION,
190 | &S_TMP_VECTOR,
191 | &P_TMP_PROPERTY);
192 |
193 | if (I_TMP_NB_INTERSECTION != 0)
194 | {
195 | B_INTERSECTION = K_TRUE;
196 | }
197 | }
198 | }
199 |
200 | P_RGB->F_RED = 0.0;
201 | P_RGB->F_GREEN = 0.0;
202 | P_RGB->F_BLUE = 0.0;
203 |
204 | if (B_INTERSECTION == K_FALSE)
205 | {
206 | *P_RGB = P_LIGHT->S_RGB;
207 |
208 | }
209 |
210 | return;
211 | }
212 |
213 | void RAYT_NORMALIZE_VECTOR(
214 | T_3D S_VECTOR,
215 | T_3D *P_NORMALIZED_VECTOR)
216 | {
217 | T_FLOAT F_VECTOR_NORME;
218 |
219 | F_VECTOR_NORME = ( (S_VECTOR.F_X * S_VECTOR.F_X) +
220 | (S_VECTOR.F_Y * S_VECTOR.F_Y) +
221 | (S_VECTOR.F_Z * S_VECTOR.F_Z) );
222 |
223 | F_VECTOR_NORME = sqrt(F_VECTOR_NORME);
224 | P_NORMALIZED_VECTOR->F_X = S_VECTOR.F_X / F_VECTOR_NORME;
225 | P_NORMALIZED_VECTOR->F_Y = S_VECTOR.F_Y / F_VECTOR_NORME;
226 | P_NORMALIZED_VECTOR->F_Z = S_VECTOR.F_Z / F_VECTOR_NORME;
227 |
228 | return;
229 | }
230 |
231 |
232 | void RAYT_TRACE(
233 | T_RAYT_RAY S_RAY,
234 | T_PTR P_OBJECT,
235 | T_UINT32 I_ITERATION,
236 | T_RAYT_RGB *P_RGB)
237 | {
238 | T_UINT32 I_INDEX,I_INDEX2;
239 | T_BOOLEAN B_INTERSECTION;
240 | T_UINT32 I_TMP_NB_INTERSECTION;
241 | T_FLOAT F_TMP_INTERSECTION;
242 | T_3D S_TMP_VECTOR;
243 | T_RAYT_PROPERTY *P_TMP_PROPERTY;
244 | T_3D S_TMP_INTERSECTION;
245 | T_FLOAT F_INTERSECTION;
246 | T_3D S_NORMAL_VECTOR;
247 | T_RAYT_PROPERTY *P_PROPERTY;
248 | T_3D S_INTERSECTION;
249 | T_RAYT_RGB S_TMP_RGB_LIGHT;
250 | T_RAYT_RGB S_RGB;
251 |
252 | T_RAYT_RAY S_R_RAY;
253 | T_RAYT_RAY S_R_RAY_FROM_LIGHT;
254 | T_RAYT_RGB S_R_RGB;
255 |
256 | T_FLOAT F_LAMBERT;
257 | T_FLOAT F_SCAL_PHONG;
258 | T_FLOAT F_SCAL_N_I;
259 | T_PTR P_OBJECT2;
260 |
261 |
262 | F_INTERSECTION = FLT_MAX;
263 |
264 | B_INTERSECTION = K_FALSE;
265 |
266 | I_ITERATION --;
267 |
268 | for (I_INDEX = 0; I_INDEX < P_RAYT_WORLD->I_NB_SPHERE; I_INDEX ++)
269 | {
270 | if (P_OBJECT != &(P_RAYT_WORLD->P_SPHERE[I_INDEX]))
271 | {
272 | RAYT_GET_FIRST_INTERSECTION_WITH_SPHERE(&S_RAY,
273 | &(P_RAYT_WORLD->P_SPHERE[I_INDEX]),
274 | &I_TMP_NB_INTERSECTION,
275 | &F_TMP_INTERSECTION,
276 | &S_TMP_INTERSECTION,
277 | &S_TMP_VECTOR,
278 | &P_TMP_PROPERTY);
279 |
280 | if (I_TMP_NB_INTERSECTION != 0)
281 | {
282 | if ((F_TMP_INTERSECTION <= F_INTERSECTION) || (B_INTERSECTION == K_FALSE))
283 | {
284 | F_INTERSECTION = F_TMP_INTERSECTION;
285 | P_PROPERTY = P_TMP_PROPERTY;
286 | S_NORMAL_VECTOR = S_TMP_VECTOR;
287 | B_INTERSECTION = K_TRUE;
288 | S_INTERSECTION = S_TMP_INTERSECTION;
289 | P_OBJECT2 = &(P_RAYT_WORLD->P_SPHERE[I_INDEX]);
290 | }
291 | }
292 | }
293 | }
294 |
295 |
296 | /* Check for other intersection and return F_INTERSECTION, P_PROPERTY and S_NORMAL_VECTOR */
297 | S_RGB.F_RED = 0.0;
298 | S_RGB.F_GREEN = 0.0;
299 | S_RGB.F_BLUE = 0.0;
300 |
301 | if (B_INTERSECTION == K_TRUE)
302 | {
303 | /* set ambiant color */
304 | S_RGB.F_RED = (P_PROPERTY->S_A.F_RED * P_RAYT_WORLD->S_AMBIANT_LIGHT.F_RED);
305 | S_RGB.F_GREEN = (P_PROPERTY->S_A.F_GREEN * P_RAYT_WORLD->S_AMBIANT_LIGHT.F_GREEN);
306 | S_RGB.F_BLUE = (P_PROPERTY->S_A.F_BLUE * P_RAYT_WORLD->S_AMBIANT_LIGHT.F_BLUE);
307 |
308 | /* COMPUTE NEW REFLECTED RAY */
309 | F_SCAL_N_I = ( S_RAY.S_VECTOR.F_X * S_NORMAL_VECTOR.F_X +
310 | S_RAY.S_VECTOR.F_Y * S_NORMAL_VECTOR.F_Y +
311 | S_RAY.S_VECTOR.F_Z * S_NORMAL_VECTOR.F_Z );
312 |
313 |
314 |
315 | S_R_RAY.S_VECTOR.F_X = -2.0 * S_NORMAL_VECTOR.F_X * F_SCAL_N_I + S_RAY.S_VECTOR.F_X;
316 | S_R_RAY.S_VECTOR.F_Y = -2.0 * S_NORMAL_VECTOR.F_Y * F_SCAL_N_I + S_RAY.S_VECTOR.F_Y;
317 | S_R_RAY.S_VECTOR.F_Z = -2.0 * S_NORMAL_VECTOR.F_Z * F_SCAL_N_I + S_RAY.S_VECTOR.F_Z;
318 |
319 | S_R_RAY.S_ORIGIN = S_INTERSECTION;
320 |
321 | /* Add lambert color */
322 | for (I_INDEX = 0; I_INDEX < P_RAYT_WORLD->I_NB_LIGHT; I_INDEX ++)
323 | {
324 | RAYT_GET_RGB_FROM_LIGHT(P_OBJECT2,
325 | &S_INTERSECTION,
326 | &(P_RAYT_WORLD->P_LIGHT[I_INDEX]),
327 | &S_TMP_VECTOR,
328 | &S_TMP_RGB_LIGHT);
329 |
330 |
331 | if ( (S_TMP_RGB_LIGHT.F_RED != 0.0) && (S_TMP_RGB_LIGHT.F_GREEN != 0.0) && (S_TMP_RGB_LIGHT.F_BLUE != 0.0) )
332 | {
333 |
334 |
335 | F_LAMBERT = S_TMP_VECTOR.F_X * S_NORMAL_VECTOR.F_X +
336 | S_TMP_VECTOR.F_Y * S_NORMAL_VECTOR.F_Y +
337 | S_TMP_VECTOR.F_Z * S_NORMAL_VECTOR.F_Z;
338 |
339 | if (F_LAMBERT >= 0.0)
340 | {
341 | S_RGB.F_RED += ( (S_TMP_RGB_LIGHT.F_RED * P_PROPERTY->S_D.F_RED) * F_LAMBERT );
342 | S_RGB.F_GREEN += ( (S_TMP_RGB_LIGHT.F_GREEN * P_PROPERTY->S_D.F_GREEN * F_LAMBERT ));
343 | S_RGB.F_BLUE += ( (S_TMP_RGB_LIGHT.F_BLUE * P_PROPERTY->S_D.F_BLUE * F_LAMBERT ));
344 |
345 |
346 | /* Calculate Refected ray form light */
347 | S_R_RAY_FROM_LIGHT.S_VECTOR.F_X = -2.0 * S_NORMAL_VECTOR.F_X * -F_LAMBERT - S_TMP_VECTOR.F_X;
348 | S_R_RAY_FROM_LIGHT.S_VECTOR.F_Y = -2.0 * S_NORMAL_VECTOR.F_Y * -F_LAMBERT - S_TMP_VECTOR.F_Y;
349 | S_R_RAY_FROM_LIGHT.S_VECTOR.F_Z = -2.0 * S_NORMAL_VECTOR.F_Z * -F_LAMBERT - S_TMP_VECTOR.F_Z;
350 |
351 |
352 | F_SCAL_PHONG = -S_R_RAY_FROM_LIGHT.S_VECTOR.F_X * S_RAY.S_VECTOR.F_X +
353 | -S_R_RAY_FROM_LIGHT.S_VECTOR.F_Y * S_RAY.S_VECTOR.F_Y +
354 | -S_R_RAY_FROM_LIGHT.S_VECTOR.F_Z * S_RAY.S_VECTOR.F_Z;
355 |
356 | if (F_SCAL_PHONG >= 0.0)
357 | {
358 | for(I_INDEX2 = 0; I_INDEX2 < P_PROPERTY->I_PHONG_NUMBER; I_INDEX2++)
359 | {
360 | F_SCAL_PHONG *= F_SCAL_PHONG;
361 | }
362 | S_RGB.F_RED += ( (S_TMP_RGB_LIGHT.F_RED * P_PROPERTY->S_P.F_RED) * F_SCAL_PHONG );
363 | S_RGB.F_GREEN += ( (S_TMP_RGB_LIGHT.F_GREEN * P_PROPERTY->S_P.F_GREEN * F_SCAL_PHONG ));
364 | S_RGB.F_BLUE += ( (S_TMP_RGB_LIGHT.F_BLUE * P_PROPERTY->S_P.F_BLUE * F_SCAL_PHONG ));
365 | }
366 |
367 | }
368 | }
369 | }
370 | /* Add reflexion color */
371 | if ( ( (P_PROPERTY->S_R.F_RED != 0.0) || (P_PROPERTY->S_R.F_GREEN != 0.0) || (P_PROPERTY->S_R.F_BLUE != 0.0) ) && (I_ITERATION > 0) )
372 | {
373 |
374 |
375 | /* trace reflected ray */
376 | RAYT_TRACE(S_R_RAY,
377 | P_OBJECT2,
378 | I_ITERATION,
379 | &S_R_RGB);
380 | S_RGB.F_RED += (P_PROPERTY->S_R.F_RED * S_R_RGB.F_RED);
381 | S_RGB.F_GREEN += (P_PROPERTY->S_R.F_GREEN * S_R_RGB.F_GREEN);
382 | S_RGB.F_BLUE += (P_PROPERTY->S_R.F_BLUE * S_R_RGB.F_BLUE);
383 |
384 | }
385 |
386 | /* Add transmission color */
387 | // if ( (P_PROPERTY->S_T.F_RED != 0.0) || (P_PROPERTY->S_T.F_GREEN != 0.0) || (P_PROPERTY->S_T.F_BLUE != 0.0) )
388 | //{
389 | /* calculate S_T_RAY transmitted RAY */
390 | // S_T_RAY.S_ORIGIN = S_INTERSECTION;
391 |
392 | //}
393 |
394 | }
395 | *P_RGB= S_RGB;
396 | }
397 |
398 | void RAYT_RENDER(
399 | T_RAYT_WORLD * P_WORLD,
400 | T_UINT32 I_ITERATION,
401 | T_UINT32 I_NB_HORIZONTAL_PIXEL,
402 | T_UINT32 I_NB_VERTICAL_PIXEL)
403 | {
404 | T_UINT32 I_HORIZONTAL_INDEX;
405 | T_UINT32 I_VERTICAL_INDEX;
406 | T_RAYT_RAY S_RAY;
407 | T_RAYT_RGB S_RAYT_RGB;
408 | T_UINT32 I_PIXEL;
409 | unsigned int frame_buffer;
410 |
411 | P_RAYT_WORLD = P_WORLD;
412 |
413 | frame_buffer = VC_get_frame_buffer();
414 |
415 | for (I_VERTICAL_INDEX = 0; I_VERTICAL_INDEX < I_NB_VERTICAL_PIXEL; I_VERTICAL_INDEX ++)
416 | {
417 | for (I_HORIZONTAL_INDEX = 0; I_HORIZONTAL_INDEX < I_NB_HORIZONTAL_PIXEL; I_HORIZONTAL_INDEX ++)
418 | {
419 | RAYT_GET_PRIMARY_RAY(I_HORIZONTAL_INDEX, I_VERTICAL_INDEX, I_NB_HORIZONTAL_PIXEL, I_NB_VERTICAL_PIXEL, &S_RAY);
420 |
421 | RAYT_TRACE(S_RAY, NULL_PTR,I_ITERATION,&S_RAYT_RGB);
422 |
423 | I_PIXEL = ((T_UINT32)0xFF) << 24;
424 |
425 | if (S_RAYT_RGB.F_RED < 1.0)
426 | {
427 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(255 * (S_RAYT_RGB.F_RED))) << 16);
428 | }
429 | else
430 | {
431 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(0xFF)) << 16);
432 | }
433 |
434 | if (S_RAYT_RGB.F_GREEN < 1.0)
435 | {
436 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(255 * (S_RAYT_RGB.F_GREEN))) << 8);
437 | }
438 | else
439 | {
440 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(0xFF)) << 8);
441 | }
442 |
443 | if (S_RAYT_RGB.F_BLUE < 1.0)
444 | {
445 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(255 * (S_RAYT_RGB.F_BLUE))));
446 | }
447 | else
448 | {
449 | I_PIXEL |= ( (T_UINT32)( (T_UINT8)(0xFF)));
450 | }
451 |
452 | *(unsigned int *)frame_buffer = I_PIXEL;
453 | frame_buffer+=4;
454 | }
455 | }
456 | return;
457 | }
458 |
--------------------------------------------------------------------------------
/src/raytracer/Raytracing.h:
--------------------------------------------------------------------------------
1 | typedef char T_CHAR;
2 | typedef short T_SHORT;
3 | typedef long T_LONG;
4 | typedef int T_INT;
5 | typedef long long T_LONG2;
6 | typedef char T_INT8;
7 | typedef short T_INT16;
8 | typedef long T_INT32;
9 |
10 |
11 |
12 | #define NULL_CHAR (T_CHAR)0
13 | #define NULL_SHORT (T_SHORT)0
14 | #define NULL_LONG (T_LONG)0
15 | #define NULL_INT (T_INT)0
16 | #define NULL_LONG2 (T_LONG2)0
17 | #define NULL_INT8 (T_INT8)0
18 | #define NULL_INT16 (T_INT16)0
19 | #define NULL_INT32 (T_INT32)0
20 |
21 |
22 | typedef unsigned char T_UCHAR;
23 | typedef unsigned short T_USHORT;
24 | typedef unsigned long T_ULONG;
25 | typedef unsigned int T_UINT;
26 | typedef unsigned long long T_ULONG2;
27 | typedef unsigned char T_UINT8;
28 | typedef unsigned short T_UINT16;
29 | typedef unsigned long T_UINT32;
30 |
31 | #define NULL_UCHAR (T_UCHAR)0
32 | #define NULL_USHORT (T_USHORT)0
33 | #define NULL_ULONG (T_ULONG)0
34 | #define NULL_UINT (T_UINT)0
35 | #define NULL_ULONG2 (T_ULONG2)0
36 | #define NULL_UINT8 (T_UINT8)0
37 | #define NULL_UINT16 (T_UINT16)0
38 | #define NULL_UINT32 (T_UINT32)0
39 |
40 | typedef float T_FLOAT;
41 | typedef double T_DOUBLE;
42 | typedef float T_FLOAT32;
43 | typedef double T_FLOAT64;
44 |
45 | #define NULL_FLOAT (T_FLOAT)0.0
46 | #define NULL_DOUBLE (T_DOUBLE)0.0
47 |
48 | typedef unsigned long T_ADDR;
49 |
50 | #define NULL_ADDR (T_ADDR)0x00000000
51 |
52 | typedef void * T_PTR;
53 |
54 | #define NULL_PTR (T_PTR)0x00000000
55 |
56 | typedef enum
57 | {
58 | K_FALSE = 0,
59 | K_TRUE = 1
60 | }T_BOOLEAN;
61 |
62 |
63 | typedef struct
64 | {
65 | T_UINT8 I_RED;
66 | T_UINT8 I_GREEN;
67 | T_UINT8 I_BLUE;
68 | } T_RGB;
69 |
70 | typedef struct
71 | {
72 | T_FLOAT F_X;
73 | T_FLOAT F_Y;
74 | } T_2D;
75 |
76 | typedef struct
77 | {
78 | T_FLOAT F_X;
79 | T_FLOAT F_Y;
80 | T_FLOAT F_Z;
81 | } T_3D;
82 |
83 | typedef struct
84 | {
85 | T_FLOAT F_X;
86 | T_FLOAT F_Y;
87 | T_FLOAT F_H;
88 | } T_2DH;
89 |
90 | typedef struct
91 | {
92 | T_FLOAT F_X;
93 | T_FLOAT F_Y;
94 | T_FLOAT F_Z;
95 | T_FLOAT F_H;
96 | } T_3DH;
97 |
98 |
99 | typedef struct
100 | {
101 | T_3D S_ORIGIN;
102 | T_3D S_VECTOR;
103 | } T_RAYT_RAY;
104 |
105 |
106 |
107 | typedef struct
108 | {
109 | T_FLOAT F_RED;
110 | T_FLOAT F_GREEN;
111 | T_FLOAT F_BLUE;
112 | } T_RAYT_RGB;
113 |
114 | typedef struct
115 | {
116 | T_RAYT_RGB S_A;
117 | T_RAYT_RGB S_D;
118 | T_RAYT_RGB S_R;
119 | T_RAYT_RGB S_P;
120 | T_UINT32 I_PHONG_NUMBER;
121 | } T_RAYT_PROPERTY;
122 |
123 | typedef struct
124 | {
125 | T_3D S_ORIGIN;
126 | T_3D S_HORIZONTAL_VECTOR;
127 | T_3D S_VERTICAL_VECTOR;
128 | } T_RAYT_WINDOW;
129 |
130 | typedef struct
131 | {
132 | T_3D S_ORIGIN;
133 | T_RAYT_RGB S_RGB;
134 | } T_RAYT_LIGHT;
135 |
136 | typedef struct
137 | {
138 | T_3D S_ORIGIN;
139 | T_FLOAT F_RADIUS;
140 | T_RAYT_PROPERTY S_PROPERTY;
141 | } T_RAYT_SPHERE;
142 |
143 | typedef struct
144 | {
145 | T_3D S_ORIGIN;
146 | T_3D S_VECTOR;
147 | T_RGB S_COLOR;
148 | } T_RAYT_PLAN;
149 |
150 | typedef struct
151 | {
152 | T_3D S_ORIGIN;
153 | T_3D S_VECTOR;
154 | T_RGB S_COLOR0;
155 | T_RGB S_COLOR1;
156 | T_FLOAT F_SQUARE_SIZE;
157 | } T_RAYT_CHESS_PLAN;
158 |
159 | typedef struct
160 | {
161 | T_3D S_EYE;
162 | T_RAYT_WINDOW S_WINDOW;
163 |
164 | T_RAYT_RGB S_AMBIANT_LIGHT;
165 |
166 | T_UINT32 I_NB_LIGHT;
167 | T_RAYT_LIGHT *P_LIGHT;
168 |
169 | T_UINT32 I_NB_SPHERE;
170 | T_RAYT_SPHERE *P_SPHERE;
171 |
172 | T_UINT32 I_NB_PLAN;
173 | T_RAYT_PLAN *P_PLAN;
174 |
175 | T_UINT32 I_NB_CHESS_PLAN;
176 | T_RAYT_CHESS_PLAN *P_CHESS_PLAN;
177 | } T_RAYT_WORLD;
178 |
179 |
180 | /* private function */
181 |
182 | void RAYT_GET_PRIMARY_RAY(
183 | T_UINT32 I_HORIZONTAL_PIXEL,
184 | T_UINT32 I_VERTICAL_PIXEL,
185 | T_UINT32 I_NB_HORIZONTAL_PIXEL,
186 | T_UINT32 I_NB_VERTICAL_PIXEL,
187 | T_RAYT_RAY *P_RAY);
188 |
189 | void RAYT_GET_REFLECTED_VECTOR(
190 | T_3D S_VECTOR,
191 | T_3D S_NORMAL_VECTOR,
192 | T_3D *P_REFLECTED_VECTOR);
193 |
194 | void RAYT_NORMALIZE_VECTOR(
195 | T_3D S_VECTOR,
196 | T_3D *P_NORMALIZED_VECTOR);
197 |
198 |
199 | void RAYT_GET_FIRST_INTERSECTION_WITH_SPHERE(
200 | T_RAYT_RAY *P_RAY,
201 | T_RAYT_SPHERE *P_SPHERE,
202 | T_UINT32 *P_NB_INTERSECTION,
203 | T_FLOAT *P_INTERSECTION_PARAM,
204 | T_3D *P_INTERSECTION,
205 | T_3D *P_NORMAL_VECTOR,
206 | T_RAYT_PROPERTY **P_PROPERTY);
207 |
208 |
209 | void RAYT_TRACE(
210 | T_RAYT_RAY S_RAY,
211 | T_PTR P_OBJECT,
212 | T_UINT32 I_ITERATION,
213 | T_RAYT_RGB *P_RGB);
214 |
215 | void RAYT_GET_3D(
216 | T_RAYT_RAY *P_RAY,
217 | T_FLOAT F_PARAMETER,
218 | T_3D *P_3D);
219 |
220 |
221 | void RAYT_GET_RGB_FROM_LIGHT(
222 | T_PTR P_OBJECT,
223 | T_3D *P_ORIGIN,
224 | T_RAYT_LIGHT *P_LIGHT,
225 | T_3D *P_VECTOR,
226 | T_RAYT_RGB *P_RGB);
227 |
228 |
229 |
230 | /* Public function */
231 |
232 | void RAYT_RENDER(
233 | T_RAYT_WORLD * P_WORLD,
234 | T_UINT32 I_ITERATION,
235 | T_UINT32 I_NB_HORIZONTAL_PIXEL,
236 | T_UINT32 I_NB_VERTICAL_PIXEL);
237 |
238 |
239 | extern T_RAYT_WORLD * P_RAYT_WORLD;
240 |
--------------------------------------------------------------------------------
/src/raytracer/VC.c:
--------------------------------------------------------------------------------
1 | #include "VC.h"
2 |
3 | extern void VC_write32 ( unsigned int, unsigned int );
4 | extern unsigned int VC_read32 ( unsigned int );
5 |
6 | void VC_write32 ( unsigned int address , unsigned int value)
7 | {
8 | *(unsigned int *)address = value;
9 | return;
10 | }
11 |
12 | unsigned int VC_read32 ( unsigned int address)
13 | {
14 | return (*(unsigned int *)address);
15 | }
16 |
17 | unsigned int VC_MailboxWrite ( unsigned int mail_address, unsigned int channel )
18 | {
19 | unsigned int mailbox;
20 |
21 | mailbox=0x2000B880;
22 | while(1)
23 | {
24 | if((VC_read32(mailbox+0x18)&0x80000000)==0) break;
25 | }
26 | VC_write32(mailbox+0x20,mail_address+channel);
27 | return(0);
28 | }
29 |
30 | unsigned int VC_MailboxRead ( unsigned int channel )
31 | {
32 | volatile unsigned int ra;
33 | unsigned int mailbox;
34 |
35 | mailbox=0x2000B880;
36 | while(1)
37 | {
38 | while(1)
39 | {
40 | ra=VC_read32(mailbox+0x18);
41 | if((ra&0x40000000)==0) break;
42 | }
43 | ra=VC_read32(mailbox+0x00);
44 | if((ra&0xF)==channel) break;
45 | }
46 | return(ra);
47 | }
48 |
49 |
50 | int VC_init ( unsigned int horizontal , unsigned int vertical )
51 | {
52 | unsigned int i;
53 | unsigned int frame_buffer;
54 |
55 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[0], horizontal); /* #0 Physical Width */
56 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[1], vertical); /* #4 Physical Height */
57 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[2], horizontal); /* #8 Virtual Width */
58 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[3], vertical); /* #12 Virtual Height */
59 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[4], 0); /* #16 GPU - Pitch */
60 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[5], 32); /* #20 Bit Depth */
61 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[6], 0); /* #24 X */
62 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[7], 0); /* #28 Y */
63 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[8], 0); /* #32 GPU - Pointer */
64 | VC_write32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[9], 0); /* #36 GPU - Size */
65 |
66 | VC_MailboxWrite((K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[0]) | K_VC_GPU_MEMORY_OFFSET,1);
67 | VC_MailboxRead(1);
68 |
69 | /* Set frame_buffer to black */
70 | frame_buffer=VC_read32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[8]);
71 | frame_buffer &=(~ K_VC_GPU_MEMORY_OFFSET);
72 | for (i = 0; i < horizontal*vertical; i++)
73 | {
74 | VC_write32(frame_buffer,0xff000000);
75 | frame_buffer+=4;
76 | }
77 | return(0);
78 | }
79 |
80 |
81 | unsigned int VC_get_frame_buffer ()
82 | {
83 | unsigned int frame_buffer;
84 |
85 | frame_buffer=VC_read32(K_VC_NOT_CACHEABLE_OFFSET + (unsigned int)&VC_aligned_buffer[8]);
86 | frame_buffer &=(~ K_VC_GPU_MEMORY_OFFSET);
87 |
88 | return frame_buffer;
89 | }
90 |
--------------------------------------------------------------------------------
/src/raytracer/VC.h:
--------------------------------------------------------------------------------
1 | extern unsigned int VC_aligned_buffer[];
2 |
3 | #define K_VC_NOT_CACHEABLE_OFFSET 0x40000000
4 | #define K_VC_GPU_MEMORY_OFFSET 0x80000000
5 |
6 | extern int VC_init (unsigned int horizontal, unsigned int vertical);
7 |
8 | extern unsigned int VC_get_frame_buffer ();
9 |
--------------------------------------------------------------------------------
/src/raytracer/VC_aligned_buffer.S:
--------------------------------------------------------------------------------
1 | .file "asm.S"
2 | .bss
3 | .align 4
4 | .globl VC_aligned_buffer
5 | VC_aligned_buffer:
6 | .space 16*4
7 |
--------------------------------------------------------------------------------
/src/raytracer/main.c:
--------------------------------------------------------------------------------
1 | #include "Raytracing.h"
2 | #include "VC.h"
3 |
4 | T_RAYT_LIGHT A_LIGHT[] =
5 | {
6 | {
7 | /* S_ORIGIN */
8 | {
9 | 0.0,
10 | 6.0,
11 | 6.0
12 | },
13 | /* COLOR */
14 | {
15 | 0.80,
16 | 0.80,
17 | 0.80
18 | }
19 | },
20 | {
21 | /* S_ORIGIN */
22 | {
23 | 20.0,
24 | 10.0,
25 | 10.0
26 | },
27 | /* COLOR */
28 | {
29 | 0.50,
30 | 0.50,
31 | 0.50
32 | }
33 | },
34 | };
35 |
36 |
37 | T_RAYT_SPHERE A_SPHERE[] =
38 | {
39 | {
40 | /* S_ORIGIN */
41 | {
42 | 15.0,
43 | 0.0,
44 | 0.0
45 | },
46 | /* RADIUS */
47 | 1.0,
48 | /* PROPERTY */
49 | {
50 | /* ambiant coef */
51 | {
52 | 255/255.0,
53 | 0/255.0,
54 | 0/255.0,
55 | },
56 | {
57 | /* diffusion coef */
58 | 255/255.0,
59 | 0/255.0,
60 | 0/255.0,
61 |
62 | },
63 | /* reflexion coef */
64 | {
65 | 1.0,
66 | 1.0,
67 | 1.0,
68 | },
69 | /* Phong coef */
70 | {
71 | 1.0,
72 | 1.0,
73 | 1.0,
74 | },
75 | 5
76 | }
77 | },
78 |
79 | {
80 | /* S_ORIGIN */
81 | {
82 | 12.0,
83 | -1.0,
84 | 2.0
85 | },
86 | /* RADIUS */
87 | 0.7,
88 | /* PROPERTY */
89 | {
90 | /* ambiant coef */
91 | {
92 | 0/255.0,
93 | 0/255.0,
94 | 255/255.0,
95 | },
96 | {
97 | /* diffusion coef */
98 | 0/255.0,
99 | 0/255.0,
100 | 255/255.0,
101 |
102 | },
103 | /* reflexion coef */
104 | {
105 | 0.2,
106 | 0.2,
107 | 0.2,
108 | },
109 | /* Phong coef */
110 | {
111 | 0.0,
112 | 0.0,
113 | 0.0,
114 | },
115 | 8
116 | }
117 | },
118 |
119 | {
120 | /* S_ORIGIN */
121 | {
122 | 12.0,
123 | 1.0,
124 | 1.0
125 | },
126 | /* RADIUS */
127 | 0.5,
128 | /* PROPERTY */
129 | {
130 | /* ambiant coef */
131 | {
132 | 0/255.0,
133 | 255/255.0,
134 | 0/255.0,
135 | },
136 | {
137 | /* diffusion coef */
138 | 0/255.0,
139 | 255/255.0,
140 | 0/255.0,
141 | },
142 | /* reflexion coef */
143 | {
144 | 0.0,
145 | 0.0,
146 | 0.0,
147 | },
148 | /* Phong coef */
149 | {
150 | 1.0,
151 | 1.0,
152 | 1.0,
153 | },
154 | 3
155 | },
156 |
157 | }
158 | };
159 |
160 |
161 | T_RAYT_WORLD S_WORLD =
162 | {
163 | /* S_EYE */
164 | {
165 | 0.0,
166 | 0.0,
167 | 0.0
168 | },
169 |
170 | /* S_WINDOW */
171 | {
172 | /* S_ORIGIN */
173 | {
174 | 10.0,
175 | -2.0,
176 | -2.0
177 | },
178 | /* S_HORIZONTAL_VECTOR */
179 | {
180 | 0.0,
181 | 0.0,
182 | 4.0
183 | },
184 | /* S_VERTICAL_VECTOR */
185 | {
186 | 0.0,
187 | 4.0,
188 | 0.0
189 | }
190 | },
191 |
192 | /* S_AMBIANT_LIGHT */
193 | {
194 | 0.4,
195 | 0.4,
196 | 0.4
197 | },
198 |
199 | /* NB LIGHT */
200 | sizeof(A_LIGHT)/sizeof(T_RAYT_LIGHT),
201 |
202 | /* P_LIGHT */
203 | A_LIGHT,
204 |
205 | /* NB SPHERE */
206 | sizeof(A_SPHERE)/sizeof(T_RAYT_SPHERE),
207 |
208 | /* P_SPHERE */
209 | A_SPHERE,
210 | };
211 |
212 |
213 | #define K_Z_BLUE_MIN ((T_FLOAT)-2.0)
214 | #define K_Z_BLUE_MAX ((T_FLOAT) 2.0)
215 | #define K_Z_GREEN_MIN ((T_FLOAT)-1.0)
216 | #define K_Z_GREEN_MAX ((T_FLOAT) 1.0)
217 |
218 | T_UINT32 I_RESOLUTION_FACTOR = 2;
219 |
220 | void main()
221 | {
222 | T_UINT32 I_H = I_RESOLUTION_FACTOR*320;
223 | T_UINT32 I_V = I_RESOLUTION_FACTOR*240;
224 |
225 | T_FLOAT F_Z_BLUE = K_Z_BLUE_MAX;
226 | T_FLOAT F_Z_GREEN = K_Z_GREEN_MAX;
227 | T_UINT32 B_BLUE_INC = 0;
228 | T_UINT32 B_GREEN_INC = 0;
229 |
230 | VC_init(I_H,I_V);
231 |
232 | while (1)
233 | {
234 | /* set sphere Z position */
235 | S_WORLD.P_SPHERE[1].S_ORIGIN.F_Z = F_Z_BLUE;
236 | S_WORLD.P_SPHERE[2].S_ORIGIN.F_Z = F_Z_GREEN;
237 |
238 | /* render image */
239 | RAYT_RENDER(&S_WORLD,4,I_H,I_V);
240 |
241 |
242 | /* modify sphere position */
243 | if (B_BLUE_INC == 0)
244 | {
245 | F_Z_BLUE -= 0.1;
246 | if (F_Z_BLUE < K_Z_BLUE_MIN )
247 | {
248 | B_BLUE_INC = 1;
249 | }
250 | }
251 | else
252 | {
253 | F_Z_BLUE += 0.1;
254 | if (F_Z_BLUE > K_Z_BLUE_MAX )
255 | {
256 | B_BLUE_INC = 0;
257 | }
258 | }
259 |
260 | if (B_GREEN_INC == 0)
261 | {
262 | F_Z_GREEN -= 0.1;
263 | if (F_Z_GREEN < K_Z_GREEN_MIN )
264 | {
265 | B_GREEN_INC = 1;
266 | }
267 | }
268 | else
269 | {
270 | F_Z_GREEN += 0.1;
271 | if (F_Z_GREEN > K_Z_GREEN_MAX )
272 | {
273 | B_GREEN_INC = 0;
274 | }
275 | }
276 |
277 | };
278 | return;
279 | }
280 |
--------------------------------------------------------------------------------
/src/semihosting/farjump-logo.c:
--------------------------------------------------------------------------------
1 | const char* farjump_logo_svg = "";
2 |
--------------------------------------------------------------------------------
/src/semihosting/semihosting.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | // Helper Macros
14 | #define LOG_EXAMPLE(FMT, ...) printf(EXAMPLE_LOGGER_PREFIX FMT, ##__VA_ARGS__)
15 | #define EXAMPLE_LOGGER_PREFIX "\n\x1b[1;46m Exemple " STR(__COUNTER__) " \x1b[0m "
16 | #define STR(a) STR_(a)
17 | #define STR_(a) #a
18 |
19 | // Helper functions
20 | static void print_stat(struct stat *sb);
21 | static void panic(const char* fmt, ...);
22 |
23 | void main(void) {
24 | // open
25 | const char* a_file = "gdb-fileio-example.svg";
26 | LOG_EXAMPLE("open(): create and open file `%s`\n", a_file);
27 | int fd = open(a_file,
28 | O_WRONLY | O_CREAT | O_TRUNC,
29 | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
30 | if (fd == -1) {
31 | panic("open(): %s", strerror(errno));
32 | }
33 |
34 | // write
35 | LOG_EXAMPLE("write(): write an SVG image in `%s`\n", a_file);
36 | extern const char* farjump_logo_svg;
37 | if (write(fd, farjump_logo_svg, strlen(farjump_logo_svg)) == -1) {
38 | panic("write(): %s", strerror(errno));
39 | }
40 |
41 | // close
42 | LOG_EXAMPLE("close(): close the file descriptor of `%s`\n", a_file);
43 | if (close(fd) == -1) {
44 | panic("close(): %s", strerror(errno));
45 | }
46 |
47 | // rename
48 | const char* new_filename = "farjump.svg";
49 | LOG_EXAMPLE("rename(): rename `%s` into `%s`\n", a_file, new_filename);
50 | if (rename(a_file, new_filename) != 0) {
51 | panic("rename(): %s", strerror(errno));
52 | }
53 |
54 | // system
55 | LOG_EXAMPLE("system(): run a shell script to check the existence of file `%s`\n", new_filename);
56 | char cmd[100];
57 | int rc;
58 | rc = snprintf(cmd, sizeof (cmd), "set -x && echo using system && test -e %s", new_filename);
59 | if (rc >= sizeof (cmd)) {
60 | panic("snprintf(): shell command buffer too small");
61 | } else if (rc <= 0) {
62 | panic("snprintf(): error code `%d`", rc);
63 | }
64 | rc = system(cmd);
65 | if (rc != 0) {
66 | panic("system(): \"%s\" returned `%d`", cmd, rc);
67 | }
68 |
69 | // stat
70 | LOG_EXAMPLE("stat(): get and print the file status of `%s`\n", new_filename);
71 | struct stat sb;
72 | if (stat(new_filename, &sb) == -1) {
73 | panic("stat(): %s", strerror(errno));
74 | }
75 | print_stat(&sb);
76 |
77 | // open
78 | LOG_EXAMPLE("open(): open file `%s` in read-only mode\n", new_filename);
79 | fd = open(new_filename, O_RDONLY);
80 | if (fd == -1) {
81 | panic("open(): %s", strerror(errno));
82 | }
83 |
84 | // read
85 | LOG_EXAMPLE("read(): partly read file `%s` and compare the retrieved data with the original data\n", new_filename);
86 | char buffer[126];
87 | int n = read(fd, buffer, sizeof (buffer));
88 | if (n == -1) {
89 | panic("read(): %s", strerror(errno));
90 | }
91 | if (n == 0) {
92 | panic("read() returned 0 bytes");
93 | }
94 | if (strncmp(buffer, farjump_logo_svg, n) != 0) {
95 | panic("bytes read from file `%s` are different from the original data", new_filename);
96 | }
97 |
98 | // lseek
99 | LOG_EXAMPLE("lseek(): partly read file `%s` and compare the retrieved data with the original data\n", new_filename);
100 | off_t offset = lseek(fd, 33, SEEK_CUR);
101 | if (offset == -1) {
102 | panic("lseek(): %s", strerror(errno));
103 | }
104 | printf("file cursor moved at %d", offset);
105 | n = read(fd, buffer, sizeof (buffer));
106 | if (n == -1) {
107 | panic("read(): %s", strerror(errno));
108 | }
109 | if (n == 0) {
110 | panic("read() returned 0 bytes");
111 | }
112 | if (strncmp(buffer, &farjump_logo_svg[offset], n) != 0) {
113 | panic("bytes read from file `%s` are different from the original data", new_filename);
114 | }
115 |
116 | // isatty
117 | LOG_EXAMPLE("isatty(): check that `%s` is indeed not a tty\n", new_filename);
118 | if (isatty(fd) != 0) {
119 | panic("isatty() did not return 0: %s", strerror(errno));
120 | }
121 |
122 | // close
123 | LOG_EXAMPLE("close(): closing file `%s`\n", new_filename);
124 | if (close(fd) == -1) {
125 | panic("close(): %s", strerror(errno));
126 | }
127 |
128 | // isatty
129 | LOG_EXAMPLE("isatty(): check that stdin is a TTY\n");
130 | if (isatty(STDIN_FILENO) != 1) {
131 | panic("isatty() did not return 1: %s", strerror(errno));
132 | }
133 |
134 | // unlink
135 | LOG_EXAMPLE("unlink(): removing file `%s`\n", new_filename);
136 | if (unlink(new_filename) == -1) {
137 | panic("unlink(): %s", strerror(errno));
138 | }
139 |
140 | // gettimeofday
141 | LOG_EXAMPLE("gettimeofday(): display current date and time\n");
142 | struct timeval tv;
143 | n = gettimeofday(&tv, NULL);
144 | if (n != 0) {
145 | panic("gettimeofday(): return code `%d`", n);
146 | }
147 | time_t nowtime = tv.tv_sec;
148 | printf("GMT-0 time is %s\n", ctime(&nowtime));
149 |
150 | // File I/Os with special files
151 | const char* dev = "/dev/random";
152 | LOG_EXAMPLE("using the File I/O extension with special file `%s`\n", dev);
153 |
154 | printf("open(): open special file `%s`\n", dev);
155 | fd = open(dev, O_RDONLY);
156 | if (fd == -1) {
157 | panic("open(): %s", strerror(errno));
158 | }
159 |
160 | printf("fstat(): get the file status of `%s`\n", dev);
161 | if (fstat(fd, &sb) == -1) {
162 | panic("fstat(): %s", strerror(errno));
163 | }
164 | print_stat(&sb);
165 |
166 | printf("read(): read some data from special file `%s`\n", dev);
167 | int x;
168 | n = read(fd, &x, sizeof (x));
169 | if (n == -1) {
170 | panic("read(): %s", strerror(errno));
171 | }
172 | if (n == 0) {
173 | panic("read() returned 0 bytes");
174 | }
175 | buffer[n] = 0;
176 | printf("read %d bytes `%d`", n, x);
177 |
178 | if (close(fd) == -1 ) {
179 | panic("close(): %s", strerror(errno));
180 | }
181 |
182 | // File I/Os with special files
183 | dev = "/dev/stdout";
184 | LOG_EXAMPLE("using the File I/O extension with special file `%s`\n", dev);
185 |
186 | printf("open(): open special file `%s`\n", dev);
187 | fd = open(dev, O_WRONLY);
188 | if (fd == -1) {
189 | panic("open(): %s", strerror(errno));
190 | }
191 |
192 | printf("fstat(): get the file status of `%s`\n", dev);
193 | if (fstat(fd, &sb) == -1) {
194 | panic("fstat(): %s", strerror(errno));
195 | }
196 | print_stat(&sb);
197 |
198 | const char data[] = "Hello, File I/O!\n";
199 | printf("write(): write `%s` to special file `%s`\n", data, dev);
200 | n = write(fd, data, sizeof (data));
201 | if (n == -1) {
202 | panic("write(): %s", strerror(errno));
203 | }
204 | if (n == 0) {
205 | panic("write() returned 0 bytes");
206 | }
207 |
208 | if (close(fd) == -1 ) {
209 | panic("close(): %s", strerror(errno));
210 | }
211 |
212 | exit(EXIT_SUCCESS);
213 | }
214 |
215 | static void panic(const char* fmt, ...) {
216 | printf("\x1b[1;41mPanic\x1b[0m ");
217 | va_list args;
218 | va_start(args, fmt);
219 | vprintf(fmt, args);
220 | va_end(args);
221 | printf("\n");
222 | exit(EXIT_FAILURE);
223 | }
224 |
225 | static void print_stat(struct stat *sb) {
226 | printf("File type: ");
227 |
228 | switch (sb->st_mode & S_IFMT) {
229 | case S_IFBLK: printf("block device\n"); break;
230 | case S_IFCHR: printf("character device\n"); break;
231 | case S_IFDIR: printf("directory\n"); break;
232 | case S_IFIFO: printf("FIFO/pipe\n"); break;
233 | case S_IFLNK: printf("symlink\n"); break;
234 | case S_IFREG: printf("regular file\n"); break;
235 | case S_IFSOCK: printf("socket\n"); break;
236 | default: printf("unknown?\n"); break;
237 | }
238 |
239 | printf("I-node number: %ld\n", (long) sb->st_ino);
240 |
241 | printf("Device ID: 0x%lx\n", (long) sb->st_rdev);
242 | printf("Container Device ID: 0x%lx\n", (long) sb->st_dev);
243 |
244 |
245 | printf("Mode: %lo (octal)\n",
246 | (unsigned long) sb->st_mode);
247 |
248 | printf("Link count: %ld\n", (long) sb->st_nlink);
249 | printf("Ownership: UID=%ld GID=%ld\n",
250 | (long) sb->st_uid, (long) sb->st_gid);
251 |
252 | printf("Preferred I/O block size: %ld bytes\n",
253 | (long) sb->st_blksize);
254 | printf("File size: %lld bytes\n",
255 | (long long) sb->st_size);
256 | printf("Blocks allocated: %lld\n",
257 | (long long) sb->st_blocks);
258 |
259 | printf("Last status change: %s", ctime(&sb->st_ctime));
260 | printf("Last file access: %s", ctime(&sb->st_atime));
261 | printf("Last file modification: %s", ctime(&sb->st_mtime));
262 | }
263 |
--------------------------------------------------------------------------------