├── .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 | Farjump Logo 2 | 3 | Alpha Alpha Logo 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 | Hello World Example 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 | RPi Address Space 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 | Using a TTL Cable 386 | 387 | Using a converter 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 | --------------------------------------------------------------------------------