├── Chapter02 ├── library │ ├── README │ ├── hello-arm │ │ ├── Makefile │ │ └── hello-arm.c │ ├── inc │ │ └── testlib.h │ ├── shared │ │ ├── Makefile │ │ └── testlib.c │ └── static │ │ ├── Makefile │ │ └── testlib.c ├── set-path-arm-cortex_a8-linux-gnueabihf └── set-path-arm-unknown-linux-gnueabi ├── Chapter03 └── 0001-BSP-for-Nova.patch ├── Chapter04 ├── build-linux-bbb.sh ├── build-linux-versatilepb.sh └── nova.dts ├── Chapter05 ├── run-qemu-initramfs.sh └── run-qemu-nfsroot.sh ├── Chapter06 ├── buildroot │ ├── board │ │ └── melp │ │ │ └── nova │ │ │ ├── 0001-BSP-for-Nova.patch │ │ │ ├── genimage.cfg │ │ │ ├── nova.dts │ │ │ ├── post-image.sh │ │ │ └── uEnv.txt │ ├── configs │ │ └── nova_defconfig │ └── package │ │ └── helloworld │ │ ├── Config.in │ │ └── helloworld.mk ├── helloworld │ ├── Makefile │ └── helloworld.c ├── poky │ └── meta-nova │ │ ├── COPYING.MIT │ │ ├── README │ │ ├── conf │ │ └── layer.conf │ │ └── recipes-local │ │ ├── helloworld │ │ ├── files │ │ │ └── helloworld.c │ │ └── helloworld_1.0.bb │ │ └── images │ │ └── nova-image.bb └── run-qemu-buildroot.sh ├── Chapter08 └── meta-ota │ ├── COPYING.MIT │ ├── README │ ├── conf │ └── layer.conf │ └── recipes-core │ └── netbase │ └── netbase_5.3.bbappend ├── Chapter09 ├── dummy-driver │ ├── Makefile │ └── dummy.c ├── gpio-int │ ├── Makefile │ ├── config-gpio.sh │ └── gpio-int.c ├── i2c-example │ ├── Makefile │ └── i2c-eeprom-read.c ├── read-urandom │ ├── Makefile │ └── read-urandom.c └── show-mac-addresses │ ├── Makefile │ └── show-mac-address.c ├── Chapter10 ├── simpleserver-systemd │ └── simpleserver.service ├── simpleserver-sysvinit │ └── init.d │ │ └── simpleserver └── simpleserver │ ├── Makefile │ └── simpleserver.c ├── Chapter11 ├── do-work │ ├── Makefile │ └── do-work.c ├── poky │ ├── build-bbb │ │ └── conf │ │ │ └── local.conf │ └── meta-bbb-pm │ │ ├── COPYING.MIT │ │ ├── README │ │ ├── conf │ │ └── layer.conf │ │ ├── recipes-bsp │ │ └── cm3-pm-firmware │ │ │ └── amx3-cm3_git.bb │ │ └── recipes-kernel │ │ └── linux │ │ ├── ti-linux-kernel-4.1 │ │ └── defconfig │ │ └── ti-linux-kernel_4.1.bb └── sysvinit-ondemand.sh ├── Chapter12 ├── condvar-demo │ ├── Makefile │ └── condvar-demo.c ├── exec-demo │ ├── Makefile │ └── exec-demo.c ├── fork-demo │ ├── Makefile │ └── fork-demo.c ├── shared-mem-demo │ ├── Makefile │ └── shared-mem-demo.c └── thread-demo │ ├── Makefile │ └── thread-demo.c ├── Chapter13 └── pagefault-demo │ ├── Makefile │ └── pagefault-demo.c ├── Chapter14 └── mbx-driver-oops │ ├── Makefile │ └── mbx.c ├── Chapter16 └── plot │ ├── README │ ├── bbb-yocto-nopreempt-floodping.dat │ ├── bbb-yocto-preempt-floodping.dat │ ├── bbb-yocto-rt-floodping.dat │ └── do-plot ├── LICENSE ├── README.md ├── copy-yoctoproject-image-to-sdcard.sh ├── format-sdcard.sh └── list-libs /Chapter02/library/README: -------------------------------------------------------------------------------- 1 | This is a demonstration of writing and linking shared and static libraries. 2 | The library file, testlib.c, contains two functions: 3 | int add_ints(int n1, int n2); 4 | int multiply_ints(int n1, int n2); 5 | 6 | There is a header file with these definitions in inc/testlib.h 7 | 8 | The directories shared/ and static/ contain identical copies of the 9 | library code but the first creates a shared library, testlib.so and 10 | the second creates a static library, testlib.a 11 | 12 | There is a program in hello-arm which links to each. 13 | Here is the directory layout: 14 | 15 | $ tree 16 | . 17 | ├── hello-arm 18 | │   ├── hello-arm.c 19 | │   └── Makefile 20 | ├── inc 21 | │   └── testlib.h 22 | ├── shared 23 | │   ├── Makefile 24 | │   └── testlib.c 25 | └── static 26 | ├── Makefile 27 | └── testlib.c 28 | 29 | Building 30 | ======== 31 | Compile the libraries first: 32 | 33 | $ cd shared 34 | $ make 35 | 36 | $ cd static 37 | $ make 38 | 39 | Then compile the application 40 | $ cd hello-arm 41 | $ make 42 | 43 | You should have two executables: hello-arm-shared and hello-arm-static 44 | $ list-libs hello-arm-shared 45 | [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 46 | 0x0000000000000001 (NEEDED) Shared library: [libtest.so] 47 | 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 48 | 49 | $ list-libs hello-arm-static 50 | [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 51 | 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 52 | 53 | 54 | Running 55 | ======= 56 | 57 | Executing the two executables gives different results: 58 | 59 | $ ./hello-arm-static 60 | Hello from ARM 61 | add_ints 62 | 4 + 5 = 9 63 | multiply_ints 64 | 4 * 5 = 20 65 | 66 | $ ./hello-arm-shared 67 | ./hello-arm-shared: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory 68 | 69 | 70 | If you add the directory containing libtest.so to the library loader path, 71 | then it works: 72 | 73 | $ LD_LIBRARY_PATH=../shared ./hello-arm-shared 74 | Hello from ARM 75 | add_ints 76 | 4 + 5 = 9 77 | multiply_ints 78 | 4 * 5 = 20 79 | 80 | 81 | -------------------------------------------------------------------------------- /Chapter02/library/hello-arm/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS := -c -Wall -I../inc 2 | PROGS := hello-arm-static hello-arm-shared 3 | 4 | all: $(PROGS) 5 | 6 | hello-arm.o: hello-arm.c 7 | $(CC) $(CFLAGS) -o $@ $^ 8 | 9 | hello-arm-static: hello-arm.o 10 | # $(CC) $(LDFLAGS) -o $@ $^ ../static/libtest.a 11 | $(CC) -o $@ $^ -L../static -ltest 12 | 13 | hello-arm-shared: hello-arm.o 14 | $(CC) -o $@ $^ -L../shared -ltest 15 | 16 | clean: 17 | rm -f *.o 18 | rm -f $(PROGS) 19 | 20 | install: 21 | cp $(PROGS) $(TARGET_DIR)/usr/local/bin 22 | -------------------------------------------------------------------------------- /Chapter02/library/hello-arm/hello-arm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main (int argc, char *argv[]) 6 | { 7 | int n1 = 4; 8 | int n2 = 5; 9 | 10 | printf("Hello from ARM\n"); 11 | printf("%d + %d = %d\n", n1, n2, add_ints(n1, n2)); 12 | printf("%d * %d = %d\n", n1, n2, multiply_ints(n1, n2)); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter02/library/inc/testlib.h: -------------------------------------------------------------------------------- 1 | int add_ints(int n1, int n2); 2 | int multiply_ints(int n1, int n2); 3 | -------------------------------------------------------------------------------- /Chapter02/library/shared/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS := -Wall -g -fPIC -I../inc 2 | OBJECTS := testlib.o 3 | 4 | all: libtest.so 5 | 6 | # Build the shared library 7 | libtest.so: $(OBJECTS) 8 | $(CC) -shared -o libtest.so $(OBJECTS) 9 | 10 | testlib.o: testlib.c 11 | $(CC) $(CFLAGS) -c testlib.c 12 | 13 | clean: 14 | rm -f $(OBJECTS) 15 | rm -f libtest.so 16 | -------------------------------------------------------------------------------- /Chapter02/library/shared/testlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "testlib.h" 3 | 4 | int add_ints(int n1, int n2) 5 | { 6 | printf("%s\n", __func__); 7 | return n1 + n2; 8 | } 9 | 10 | int multiply_ints(int n1, int n2) 11 | { 12 | printf("%s\n", __func__); 13 | return n1 * n2; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter02/library/static/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -Wall -g -I../inc 2 | OBJECTS = testlib.o 3 | 4 | all: libtest.a 5 | 6 | # Build the static library 7 | libtest.a: $(OBJECTS) 8 | ar rc libtest.a $(OBJECTS) 9 | 10 | testlib.o: testlib.c 11 | $(CC) $(CFLAGS) -c testlib.c 12 | 13 | clean: 14 | rm -f $(OBJECTS) 15 | rm -f libtest.a 16 | -------------------------------------------------------------------------------- /Chapter02/library/static/testlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "testlib.h" 3 | 4 | int add_ints(int n1, int n2) 5 | { 6 | printf("%s\n", __func__); 7 | return n1 + n2; 8 | } 9 | 10 | int multiply_ints(int n1, int n2) 11 | { 12 | printf("%s\n", __func__); 13 | return n1 * n2; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter02/set-path-arm-cortex_a8-linux-gnueabihf: -------------------------------------------------------------------------------- 1 | # Add a toolchain created using CrosstoolNG to your path 2 | # and export ARCH and CROSS_COMPILE variables ready to 3 | # compile U-Boot, Linux, Busybox and anything else using 4 | # the Kconfig/Kbuild scripts 5 | 6 | # Chris Simmonds, chris@2net.co.uk 7 | 8 | PATH=${HOME}/x-tools/arm-cortex_a8-linux-gnueabihf/bin/:$PATH 9 | export CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- 10 | export ARCH=arm 11 | -------------------------------------------------------------------------------- /Chapter02/set-path-arm-unknown-linux-gnueabi: -------------------------------------------------------------------------------- 1 | # Add a toolchain created using CrosstoolNG to your path 2 | # and export ARCH and CROSS_COMPILE variables ready to 3 | # compile U-Boot, Linux, Busybox and anything else using 4 | # the Kconfig/Kbuild scripts 5 | 6 | # Chris Simmonds, chris@2net.co.uk 7 | 8 | PATH=${HOME}/x-tools/arm-unknown-linux-gnueabi/bin/:$PATH 9 | export CROSS_COMPILE=arm-unknown-linux-gnueabi- 10 | export ARCH=arm 11 | -------------------------------------------------------------------------------- /Chapter03/0001-BSP-for-Nova.patch: -------------------------------------------------------------------------------- 1 | From e160f8293446922183f02c7008ea34a4341f3960 Mon Sep 17 00:00:00 2001 2 | From: Chris Simmonds 3 | Date: Thu, 20 Apr 2017 16:56:17 +0100 4 | Subject: [PATCH] BSP for Nova 5 | 6 | --- 7 | arch/arm/Kconfig | 1 + 8 | arch/arm/mach-omap2/am33xx/Kconfig | 9 + 9 | board/ti/nova/Kconfig | 43 ++ 10 | board/ti/nova/MAINTAINERS | 12 + 11 | board/ti/nova/Makefile | 13 + 12 | board/ti/nova/README | 205 +++++++++ 13 | board/ti/nova/board.c | 879 +++++++++++++++++++++++++++++++++++++ 14 | board/ti/nova/board.h | 82 ++++ 15 | board/ti/nova/mux.c | 403 +++++++++++++++++ 16 | board/ti/nova/u-boot.lds | 158 +++++++ 17 | configs/nova_defconfig | 46 ++ 18 | include/configs/nova.h | 421 ++++++++++++++++++ 19 | 12 files changed, 2272 insertions(+) 20 | create mode 100644 board/ti/nova/Kconfig 21 | create mode 100644 board/ti/nova/MAINTAINERS 22 | create mode 100644 board/ti/nova/Makefile 23 | create mode 100644 board/ti/nova/README 24 | create mode 100644 board/ti/nova/board.c 25 | create mode 100644 board/ti/nova/board.h 26 | create mode 100644 board/ti/nova/mux.c 27 | create mode 100644 board/ti/nova/u-boot.lds 28 | create mode 100644 configs/nova_defconfig 29 | create mode 100644 include/configs/nova.h 30 | 31 | diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig 32 | index 0ed36cd..220e065 100644 33 | --- a/arch/arm/Kconfig 34 | +++ b/arch/arm/Kconfig 35 | @@ -1066,6 +1066,7 @@ source "board/vscom/baltos/Kconfig" 36 | source "board/woodburn/Kconfig" 37 | source "board/work-microwave/work_92105/Kconfig" 38 | source "board/zipitz2/Kconfig" 39 | +source "board/ti/nova/Kconfig" 40 | 41 | source "arch/arm/Kconfig.debug" 42 | 43 | diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig 44 | index 56c4406..f93249e 100644 45 | --- a/arch/arm/mach-omap2/am33xx/Kconfig 46 | +++ b/arch/arm/mach-omap2/am33xx/Kconfig 47 | @@ -18,6 +18,15 @@ config TARGET_AM335X_EVM 48 | to write software and develop hardware around 49 | an AM335x processor subsystem. 50 | 51 | +config TARGET_NOVA 52 | + bool "Support the Nova! board" 53 | + select DM 54 | + select DM_SERIAL 55 | + select DM_GPIO 56 | + select TI_I2C_BOARD_DETECT 57 | + help 58 | + The Nova target board 59 | + 60 | config TARGET_AM335X_BALTOS 61 | bool "Support am335x_baltos" 62 | select DM 63 | diff --git a/board/ti/nova/Kconfig b/board/ti/nova/Kconfig 64 | new file mode 100644 65 | index 0000000..c8a5c4f 66 | --- /dev/null 67 | +++ b/board/ti/nova/Kconfig 68 | @@ -0,0 +1,43 @@ 69 | +if TARGET_NOVA 70 | + 71 | +config SPL_ENV_SUPPORT 72 | + default y 73 | + 74 | +config SPL_WATCHDOG_SUPPORT 75 | + default y 76 | + 77 | +config SPL_YMODEM_SUPPORT 78 | + default y 79 | + 80 | +config SYS_BOARD 81 | + default "nova" 82 | + 83 | +config SYS_VENDOR 84 | + default "ti" 85 | + 86 | +config SYS_SOC 87 | + default "am33xx" 88 | + 89 | +config SYS_CONFIG_NAME 90 | + default "nova" 91 | + 92 | +config CONS_INDEX 93 | + int "UART used for console" 94 | + range 1 6 95 | + default 1 96 | + help 97 | + The AM335x SoC has a total of 6 UARTs (UART0 to UART5 as referenced 98 | + in documentation, etc) available to it. Depending on your specific 99 | + board you may want something other than UART0 as for example the IDK 100 | + uses UART3 so enter 4 here. 101 | + 102 | +config NOR 103 | + bool "Support for NOR flash" 104 | + help 105 | + The AM335x SoC supports having a NOR flash connected to the GPMC. 106 | + In practice this is seen as a NOR flash module connected to the 107 | + "memory cape" for the BeagleBone family. 108 | + 109 | +source "board/ti/common/Kconfig" 110 | + 111 | +endif 112 | diff --git a/board/ti/nova/MAINTAINERS b/board/ti/nova/MAINTAINERS 113 | new file mode 100644 114 | index 0000000..c99e06d 115 | --- /dev/null 116 | +++ b/board/ti/nova/MAINTAINERS 117 | @@ -0,0 +1,12 @@ 118 | +AM335X BOARD 119 | +M: Tom Rini 120 | +S: Maintained 121 | +F: board/ti/am335x/ 122 | +F: include/configs/am335x_evm.h 123 | +F: configs/am335x_boneblack_defconfig 124 | +F: configs/am335x_boneblack_vboot_defconfig 125 | +F: configs/am335x_evm_defconfig 126 | +F: configs/am335x_evm_nor_defconfig 127 | +F: configs/am335x_evm_norboot_defconfig 128 | +F: configs/am335x_evm_spiboot_defconfig 129 | +F: configs/am335x_evm_usbspl_defconfig 130 | diff --git a/board/ti/nova/Makefile b/board/ti/nova/Makefile 131 | new file mode 100644 132 | index 0000000..804ac37 133 | --- /dev/null 134 | +++ b/board/ti/nova/Makefile 135 | @@ -0,0 +1,13 @@ 136 | +# 137 | +# Makefile 138 | +# 139 | +# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 140 | +# 141 | +# SPDX-License-Identifier: GPL-2.0+ 142 | +# 143 | + 144 | +ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),) 145 | +obj-y := mux.o 146 | +endif 147 | + 148 | +obj-y += board.o 149 | diff --git a/board/ti/nova/README b/board/ti/nova/README 150 | new file mode 100644 151 | index 0000000..19e0ecc 152 | --- /dev/null 153 | +++ b/board/ti/nova/README 154 | @@ -0,0 +1,205 @@ 155 | +Summary 156 | +======= 157 | + 158 | +This document covers various features of the 'am335x_evm' build, and some of 159 | +the related build targets (am335x_evm_uartN, etc). 160 | + 161 | +Hardware 162 | +======== 163 | + 164 | +The binary produced by this board supports, based on parsing of the EEPROM 165 | +documented in TI's reference designs: 166 | +- AM335x GP EVM 167 | +- AM335x EVM SK 168 | +- Beaglebone White 169 | +- Beaglebone Black 170 | + 171 | +Customization 172 | +============= 173 | + 174 | +Given that all of the above boards are reference platforms (and the 175 | +Beaglebone platforms are OSHA), it is likely that this platform code and 176 | +configuration will be used as the basis of a custom platform. It is 177 | +worth noting that aside from things such as NAND or MMC only being 178 | +required if a custom platform makes use of these blocks, the following 179 | +are required, depending on design: 180 | + 181 | +- GPIO is only required if DDR3 power is controlled in a way similar to 182 | + EVM SK 183 | +- SPI is only required for SPI flash, or exposing the SPI bus. 184 | + 185 | +The following blocks are required: 186 | +- I2C, to talk with the PMIC and ensure that we do not run afoul of 187 | + errata 1.0.24. 188 | + 189 | +When removing options as part of customization, 190 | +CONFIG_EXTRA_ENV_SETTINGS will need additional care to update for your 191 | +needs and to remove no longer relevant options as in some cases we 192 | +define additional text blocks (such as for NAND or DFU strings). Also 193 | +note that all of the SPL options are grouped together, rather than with 194 | +the IP blocks, so both areas will need their choices updated to reflect 195 | +the custom design. 196 | + 197 | +NAND 198 | +==== 199 | + 200 | +The AM335x GP EVM ships with a 256MiB NAND available in most profiles. In 201 | +this example to program the NAND we assume that an SD card has been 202 | +inserted with the files to write in the first SD slot and that mtdparts 203 | +have been configured correctly for the board. All images are first loaded 204 | +into memory, then written to NAND. 205 | + 206 | +Step-1: Building u-boot for NAND boot 207 | + Set following CONFIGxx options for NAND device. 208 | + CONFIG_SYS_NAND_PAGE_SIZE number of main bytes in NAND page 209 | + CONFIG_SYS_NAND_OOBSIZE number of OOB bytes in NAND page 210 | + CONFIG_SYS_NAND_BLOCK_SIZE number of bytes in NAND erase-block 211 | + CONFIG_SYS_NAND_ECCPOS ECC map for NAND page 212 | + CONFIG_NAND_OMAP_ECCSCHEME (refer doc/README.nand) 213 | + 214 | +Step-2: Flashing NAND via MMC/SD 215 | + # select BOOTSEL to MMC/SD boot and boot from MMC/SD card 216 | + U-Boot # mmc rescan 217 | + # erase flash 218 | + U-Boot # nand erase.chip 219 | + U-Boot # env default -f -a 220 | + U-Boot # saveenv 221 | + # flash MLO. Redundant copies of MLO are kept for failsafe 222 | + U-Boot # load mmc 0 0x82000000 MLO 223 | + U-Boot # nand write 0x82000000 0x00000 0x20000 224 | + U-Boot # nand write 0x82000000 0x20000 0x20000 225 | + U-Boot # nand write 0x82000000 0x40000 0x20000 226 | + U-Boot # nand write 0x82000000 0x60000 0x20000 227 | + # flash u-boot.img 228 | + U-Boot # load mmc 0 0x82000000 u-boot.img 229 | + U-Boot # nand write 0x82000000 0x80000 0x60000 230 | + # flash kernel image 231 | + U-Boot # load mmc 0 0x82000000 uImage 232 | + U-Boot # nand write 0x82000000 ${nandsrcaddr} ${nandimgsize} 233 | + # flash filesystem image 234 | + U-Boot # load mmc 0 0x82000000 filesystem.img 235 | + U-Boot # nand write 0x82000000 ${loadaddress} 0x300000 236 | + 237 | +Step-3: Set BOOTSEL pin to select NAND boot, and POR the device. 238 | + The device should boot from images flashed on NAND device. 239 | + 240 | +NOR 241 | +=== 242 | + 243 | +The Beaglebone White can be equipped with a "memory cape" that in turn can 244 | +have a NOR module plugged into it. In this case it is then possible to 245 | +program and boot from NOR. Note that due to how U-Boot is designed we 246 | +must build a specific version of U-Boot that knows we have NOR flash. This 247 | +build is named 'am335x_evm_nor'. Further, we have a 'am335x_evm_norboot' 248 | +build that will assume that the environment is on NOR rather than NAND. In 249 | +the following example we assume that and SD card has been populated with 250 | +MLO and u-boot.img from a 'am335x_evm_nor' build and also contains the 251 | +'u-boot.bin' from a 'am335x_evm_norboot' build. When booting from NOR, a 252 | +binary must be written to the start of NOR, with no header or similar 253 | +prepended. In the following example we use a size of 512KiB (0x80000) 254 | +as that is how much space we set aside before the environment, as per 255 | +the config file. 256 | + 257 | +U-Boot # mmc rescan 258 | +U-Boot # load mmc 0 ${loadaddr} u-boot.bin 259 | +U-Boot # protect off 08000000 +80000 260 | +U-Boot # erase 08000000 +80000 261 | +U-Boot # cp.b ${loadaddr} 08000000 ${filesize} 262 | + 263 | +Falcon Mode 264 | +=========== 265 | + 266 | +The default build includes "Falcon Mode" (see doc/README.falcon) via NAND, 267 | +eMMC (or raw SD cards) and FAT SD cards. Our default behavior currently is 268 | +to read a 'c' on the console while in SPL at any point prior to loading the 269 | +OS payload (so as soon as possible) to opt to booting full U-Boot. Also 270 | +note that while one can program Falcon Mode "in place" great care needs to 271 | +be taken by the user to not 'brick' their setup. As these are all eval 272 | +boards with multiple boot methods, recovery should not be an issue in this 273 | +worst-case however. 274 | + 275 | +Falcon Mode: eMMC 276 | +================= 277 | + 278 | +The recommended layout in this case is: 279 | + 280 | +MMC BLOCKS |--------------------------------| LOCATION IN BYTES 281 | +0x0000 - 0x007F : MBR or GPT table : 0x000000 - 0x020000 282 | +0x0080 - 0x00FF : ARGS or FDT file : 0x010000 - 0x020000 283 | +0x0100 - 0x01FF : SPL.backup1 (first copy used) : 0x020000 - 0x040000 284 | +0x0200 - 0x02FF : SPL.backup2 (second copy used) : 0x040000 - 0x060000 285 | +0x0300 - 0x06FF : U-Boot : 0x060000 - 0x0e0000 286 | +0x0700 - 0x08FF : U-Boot Env + Redundant : 0x0e0000 - 0x120000 287 | +0x0900 - 0x28FF : Kernel : 0x120000 - 0x520000 288 | + 289 | +Note that when we run 'spl export' it will prepare to boot the kernel. 290 | +This includes relocation of the uImage from where we loaded it to the entry 291 | +point defined in the header. As these locations overlap by default, it 292 | +would leave us with an image that if written to MMC will not boot, so 293 | +instead of using the loadaddr variable we use 0x81000000 in the following 294 | +example. In this example we are loading from the network, for simplicity, 295 | +and assume a valid partition table already exists and 'mmc dev' has already 296 | +been run to select the correct device. Also note that if you previously 297 | +had a FAT partition (such as on a Beaglebone Black) it is not enough to 298 | +write garbage into the area, you must delete it from the partition table 299 | +first. 300 | + 301 | +# Ensure we are able to talk with this mmc device 302 | +U-Boot # mmc rescan 303 | +U-Boot # tftp 81000000 am335x/MLO 304 | +# Write to two of the backup locations ROM uses 305 | +U-Boot # mmc write 81000000 100 100 306 | +U-Boot # mmc write 81000000 200 100 307 | +# Write U-Boot to the location set in the config 308 | +U-Boot # tftp 81000000 am335x/u-boot.img 309 | +U-Boot # mmc write 81000000 300 400 310 | +# Load kernel and device tree into memory, perform export 311 | +U-Boot # tftp 81000000 am335x/uImage 312 | +U-Boot # run findfdt 313 | +U-Boot # tftp ${fdtaddr} am335x/${fdtfile} 314 | +U-Boot # run mmcargs 315 | +U-Boot # spl export fdt 81000000 - ${fdtaddr} 316 | +# Write the updated device tree to MMC 317 | +U-Boot # mmc write ${fdtaddr} 80 80 318 | +# Write the uImage to MMC 319 | +U-Boot # mmc write 81000000 900 2000 320 | + 321 | +Falcon Mode: FAT SD cards 322 | +========================= 323 | + 324 | +In this case the additional file is written to the filesystem. In this 325 | +example we assume that the uImage and device tree to be used are already on 326 | +the FAT filesystem (only the uImage MUST be for this to function 327 | +afterwards) along with a Falcon Mode aware MLO and the FAT partition has 328 | +already been created and marked bootable: 329 | + 330 | +U-Boot # mmc rescan 331 | +# Load kernel and device tree into memory, perform export 332 | +U-Boot # load mmc 0:1 ${loadaddr} uImage 333 | +U-Boot # run findfdt 334 | +U-Boot # load mmc 0:1 ${fdtaddr} ${fdtfile} 335 | +U-Boot # run mmcargs 336 | +U-Boot # spl export fdt ${loadaddr} - ${fdtaddr} 337 | + 338 | +This will print a number of lines and then end with something like: 339 | + Using Device Tree in place at 80f80000, end 80f85928 340 | + Using Device Tree in place at 80f80000, end 80f88928 341 | +So then you: 342 | + 343 | +U-Boot # fatwrite mmc 0:1 0x80f80000 args 8928 344 | + 345 | +Falcon Mode: NAND 346 | +================= 347 | + 348 | +In this case the additional data is written to another partition of the 349 | +NAND. In this example we assume that the uImage and device tree to be are 350 | +already located on the NAND somewhere (such as filesystem or mtd partition) 351 | +along with a Falcon Mode aware MLO written to the correct locations for 352 | +booting and mtdparts have been configured correctly for the board: 353 | + 354 | +U-Boot # nand read ${loadaddr} kernel 355 | +U-Boot # load nand rootfs ${fdtaddr} /boot/am335x-evm.dtb 356 | +U-Boot # run nandargs 357 | +U-Boot # spl export fdt ${loadaddr} - ${fdtaddr} 358 | +U-Boot # nand erase.part u-boot-spl-os 359 | +U-Boot # nand write ${fdtaddr} u-boot-spl-os 360 | diff --git a/board/ti/nova/board.c b/board/ti/nova/board.c 361 | new file mode 100644 362 | index 0000000..8eaf3e9 363 | --- /dev/null 364 | +++ b/board/ti/nova/board.c 365 | @@ -0,0 +1,879 @@ 366 | +/* 367 | + * board.c 368 | + * 369 | + * Board functions for TI AM335X based boards 370 | + * 371 | + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ 372 | + * 373 | + * SPDX-License-Identifier: GPL-2.0+ 374 | + */ 375 | + 376 | +#include 377 | +#include 378 | +#include 379 | +#include 380 | +#include 381 | +#include 382 | +#include 383 | +#include 384 | +#include 385 | +#include 386 | +#include 387 | +#include 388 | +#include 389 | +#include 390 | +#include 391 | +#include 392 | +#include 393 | +#include 394 | +#include 395 | +#include 396 | +#include 397 | +#include 398 | +#include 399 | +#include 400 | +#include 401 | +#include 402 | +#include "../common/board_detect.h" 403 | +#include "board.h" 404 | + 405 | +DECLARE_GLOBAL_DATA_PTR; 406 | + 407 | +/* GPIO that controls power to DDR on EVM-SK */ 408 | +#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) 409 | +#define GPIO_DDR_VTT_EN GPIO_TO_PIN(0, 7) 410 | +#define ICE_GPIO_DDR_VTT_EN GPIO_TO_PIN(0, 18) 411 | +#define GPIO_PR1_MII_CTRL GPIO_TO_PIN(3, 4) 412 | +#define GPIO_MUX_MII_CTRL GPIO_TO_PIN(3, 10) 413 | +#define GPIO_FET_SWITCH_CTRL GPIO_TO_PIN(0, 7) 414 | +#define GPIO_PHY_RESET GPIO_TO_PIN(2, 5) 415 | +#define GPIO_ETH0_MODE GPIO_TO_PIN(0, 11) 416 | +#define GPIO_ETH1_MODE GPIO_TO_PIN(1, 26) 417 | + 418 | +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 419 | + 420 | +#define GPIO0_RISINGDETECT (AM33XX_GPIO0_BASE + OMAP_GPIO_RISINGDETECT) 421 | +#define GPIO1_RISINGDETECT (AM33XX_GPIO1_BASE + OMAP_GPIO_RISINGDETECT) 422 | + 423 | +#define GPIO0_IRQSTATUS1 (AM33XX_GPIO0_BASE + OMAP_GPIO_IRQSTATUS1) 424 | +#define GPIO1_IRQSTATUS1 (AM33XX_GPIO1_BASE + OMAP_GPIO_IRQSTATUS1) 425 | + 426 | +#define GPIO0_IRQSTATUSRAW (AM33XX_GPIO0_BASE + 0x024) 427 | +#define GPIO1_IRQSTATUSRAW (AM33XX_GPIO1_BASE + 0x024) 428 | + 429 | +/* 430 | + * Read header information from EEPROM into global structure. 431 | + */ 432 | +#ifdef CONFIG_TI_I2C_BOARD_DETECT 433 | +void do_board_detect(void) 434 | +{ 435 | + enable_i2c0_pin_mux(); 436 | + i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE); 437 | + 438 | + if (ti_i2c_eeprom_am_get(-1, CONFIG_SYS_I2C_EEPROM_ADDR)) 439 | + printf("ti_i2c_eeprom_init failed\n"); 440 | +} 441 | +#endif 442 | + 443 | +#ifndef CONFIG_DM_SERIAL 444 | +struct serial_device *default_serial_console(void) 445 | +{ 446 | + if (board_is_icev2()) 447 | + return &eserial4_device; 448 | + else 449 | + return &eserial1_device; 450 | +} 451 | +#endif 452 | + 453 | +#ifndef CONFIG_SKIP_LOWLEVEL_INIT 454 | +static const struct ddr_data ddr2_data = { 455 | + .datardsratio0 = MT47H128M16RT25E_RD_DQS, 456 | + .datafwsratio0 = MT47H128M16RT25E_PHY_FIFO_WE, 457 | + .datawrsratio0 = MT47H128M16RT25E_PHY_WR_DATA, 458 | +}; 459 | + 460 | +static const struct cmd_control ddr2_cmd_ctrl_data = { 461 | + .cmd0csratio = MT47H128M16RT25E_RATIO, 462 | + 463 | + .cmd1csratio = MT47H128M16RT25E_RATIO, 464 | + 465 | + .cmd2csratio = MT47H128M16RT25E_RATIO, 466 | +}; 467 | + 468 | +static const struct emif_regs ddr2_emif_reg_data = { 469 | + .sdram_config = MT47H128M16RT25E_EMIF_SDCFG, 470 | + .ref_ctrl = MT47H128M16RT25E_EMIF_SDREF, 471 | + .sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1, 472 | + .sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2, 473 | + .sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3, 474 | + .emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY, 475 | +}; 476 | + 477 | +static const struct emif_regs ddr2_evm_emif_reg_data = { 478 | + .sdram_config = MT47H128M16RT25E_EMIF_SDCFG, 479 | + .ref_ctrl = MT47H128M16RT25E_EMIF_SDREF, 480 | + .sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1, 481 | + .sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2, 482 | + .sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3, 483 | + .ocp_config = EMIF_OCP_CONFIG_AM335X_EVM, 484 | + .emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY, 485 | +}; 486 | + 487 | +static const struct ddr_data ddr3_data = { 488 | + .datardsratio0 = MT41J128MJT125_RD_DQS, 489 | + .datawdsratio0 = MT41J128MJT125_WR_DQS, 490 | + .datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE, 491 | + .datawrsratio0 = MT41J128MJT125_PHY_WR_DATA, 492 | +}; 493 | + 494 | +static const struct ddr_data ddr3_beagleblack_data = { 495 | + .datardsratio0 = MT41K256M16HA125E_RD_DQS, 496 | + .datawdsratio0 = MT41K256M16HA125E_WR_DQS, 497 | + .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, 498 | + .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, 499 | +}; 500 | + 501 | +static const struct ddr_data ddr3_evm_data = { 502 | + .datardsratio0 = MT41J512M8RH125_RD_DQS, 503 | + .datawdsratio0 = MT41J512M8RH125_WR_DQS, 504 | + .datafwsratio0 = MT41J512M8RH125_PHY_FIFO_WE, 505 | + .datawrsratio0 = MT41J512M8RH125_PHY_WR_DATA, 506 | +}; 507 | + 508 | +static const struct ddr_data ddr3_icev2_data = { 509 | + .datardsratio0 = MT41J128MJT125_RD_DQS_400MHz, 510 | + .datawdsratio0 = MT41J128MJT125_WR_DQS_400MHz, 511 | + .datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE_400MHz, 512 | + .datawrsratio0 = MT41J128MJT125_PHY_WR_DATA_400MHz, 513 | +}; 514 | + 515 | +static const struct cmd_control ddr3_cmd_ctrl_data = { 516 | + .cmd0csratio = MT41J128MJT125_RATIO, 517 | + .cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT, 518 | + 519 | + .cmd1csratio = MT41J128MJT125_RATIO, 520 | + .cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT, 521 | + 522 | + .cmd2csratio = MT41J128MJT125_RATIO, 523 | + .cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT, 524 | +}; 525 | + 526 | +static const struct cmd_control ddr3_beagleblack_cmd_ctrl_data = { 527 | + .cmd0csratio = MT41K256M16HA125E_RATIO, 528 | + .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 529 | + 530 | + .cmd1csratio = MT41K256M16HA125E_RATIO, 531 | + .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 532 | + 533 | + .cmd2csratio = MT41K256M16HA125E_RATIO, 534 | + .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 535 | +}; 536 | + 537 | +static const struct cmd_control ddr3_evm_cmd_ctrl_data = { 538 | + .cmd0csratio = MT41J512M8RH125_RATIO, 539 | + .cmd0iclkout = MT41J512M8RH125_INVERT_CLKOUT, 540 | + 541 | + .cmd1csratio = MT41J512M8RH125_RATIO, 542 | + .cmd1iclkout = MT41J512M8RH125_INVERT_CLKOUT, 543 | + 544 | + .cmd2csratio = MT41J512M8RH125_RATIO, 545 | + .cmd2iclkout = MT41J512M8RH125_INVERT_CLKOUT, 546 | +}; 547 | + 548 | +static const struct cmd_control ddr3_icev2_cmd_ctrl_data = { 549 | + .cmd0csratio = MT41J128MJT125_RATIO_400MHz, 550 | + .cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT_400MHz, 551 | + 552 | + .cmd1csratio = MT41J128MJT125_RATIO_400MHz, 553 | + .cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT_400MHz, 554 | + 555 | + .cmd2csratio = MT41J128MJT125_RATIO_400MHz, 556 | + .cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT_400MHz, 557 | +}; 558 | + 559 | +static struct emif_regs ddr3_emif_reg_data = { 560 | + .sdram_config = MT41J128MJT125_EMIF_SDCFG, 561 | + .ref_ctrl = MT41J128MJT125_EMIF_SDREF, 562 | + .sdram_tim1 = MT41J128MJT125_EMIF_TIM1, 563 | + .sdram_tim2 = MT41J128MJT125_EMIF_TIM2, 564 | + .sdram_tim3 = MT41J128MJT125_EMIF_TIM3, 565 | + .zq_config = MT41J128MJT125_ZQ_CFG, 566 | + .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY | 567 | + PHY_EN_DYN_PWRDN, 568 | +}; 569 | + 570 | +static struct emif_regs ddr3_beagleblack_emif_reg_data = { 571 | + .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, 572 | + .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, 573 | + .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, 574 | + .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, 575 | + .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, 576 | + .ocp_config = EMIF_OCP_CONFIG_BEAGLEBONE_BLACK, 577 | + .zq_config = MT41K256M16HA125E_ZQ_CFG, 578 | + .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, 579 | +}; 580 | + 581 | +static struct emif_regs ddr3_evm_emif_reg_data = { 582 | + .sdram_config = MT41J512M8RH125_EMIF_SDCFG, 583 | + .ref_ctrl = MT41J512M8RH125_EMIF_SDREF, 584 | + .sdram_tim1 = MT41J512M8RH125_EMIF_TIM1, 585 | + .sdram_tim2 = MT41J512M8RH125_EMIF_TIM2, 586 | + .sdram_tim3 = MT41J512M8RH125_EMIF_TIM3, 587 | + .ocp_config = EMIF_OCP_CONFIG_AM335X_EVM, 588 | + .zq_config = MT41J512M8RH125_ZQ_CFG, 589 | + .emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY | 590 | + PHY_EN_DYN_PWRDN, 591 | +}; 592 | + 593 | +static struct emif_regs ddr3_icev2_emif_reg_data = { 594 | + .sdram_config = MT41J128MJT125_EMIF_SDCFG_400MHz, 595 | + .ref_ctrl = MT41J128MJT125_EMIF_SDREF_400MHz, 596 | + .sdram_tim1 = MT41J128MJT125_EMIF_TIM1_400MHz, 597 | + .sdram_tim2 = MT41J128MJT125_EMIF_TIM2_400MHz, 598 | + .sdram_tim3 = MT41J128MJT125_EMIF_TIM3_400MHz, 599 | + .zq_config = MT41J128MJT125_ZQ_CFG_400MHz, 600 | + .emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY_400MHz | 601 | + PHY_EN_DYN_PWRDN, 602 | +}; 603 | + 604 | +#ifdef CONFIG_SPL_OS_BOOT 605 | +int spl_start_uboot(void) 606 | +{ 607 | + /* break into full u-boot on 'c' */ 608 | + if (serial_tstc() && serial_getc() == 'c') 609 | + return 1; 610 | + 611 | +#ifdef CONFIG_SPL_ENV_SUPPORT 612 | + env_init(); 613 | + env_relocate_spec(); 614 | + if (getenv_yesno("boot_os") != 1) 615 | + return 1; 616 | +#endif 617 | + 618 | + return 0; 619 | +} 620 | +#endif 621 | + 622 | +#define OSC (V_OSCK/1000000) 623 | +const struct dpll_params dpll_ddr = { 624 | + 266, OSC-1, 1, -1, -1, -1, -1}; 625 | +const struct dpll_params dpll_ddr_evm_sk = { 626 | + 303, OSC-1, 1, -1, -1, -1, -1}; 627 | +const struct dpll_params dpll_ddr_bone_black = { 628 | + 400, OSC-1, 1, -1, -1, -1, -1}; 629 | + 630 | +void am33xx_spl_board_init(void) 631 | +{ 632 | + int mpu_vdd; 633 | + 634 | + /* Get the frequency */ 635 | + dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev); 636 | + 637 | + if (board_is_bone() || board_is_bone_lt()) { 638 | + /* BeagleBone PMIC Code */ 639 | + int usb_cur_lim; 640 | + 641 | + /* 642 | + * Only perform PMIC configurations if board rev > A1 643 | + * on Beaglebone White 644 | + */ 645 | + if (board_is_bone() && !strncmp(board_ti_get_rev(), "00A1", 4)) 646 | + return; 647 | + 648 | + if (i2c_probe(TPS65217_CHIP_PM)) 649 | + return; 650 | + 651 | + /* 652 | + * On Beaglebone White we need to ensure we have AC power 653 | + * before increasing the frequency. 654 | + */ 655 | + if (board_is_bone()) { 656 | + uchar pmic_status_reg; 657 | + if (tps65217_reg_read(TPS65217_STATUS, 658 | + &pmic_status_reg)) 659 | + return; 660 | + if (!(pmic_status_reg & TPS65217_PWR_SRC_AC_BITMASK)) { 661 | + puts("No AC power, disabling frequency switch\n"); 662 | + return; 663 | + } 664 | + } 665 | + 666 | + /* 667 | + * Override what we have detected since we know if we have 668 | + * a Beaglebone Black it supports 1GHz. 669 | + */ 670 | + if (board_is_bone_lt()) 671 | + dpll_mpu_opp100.m = MPUPLL_M_1000; 672 | + 673 | + /* 674 | + * Increase USB current limit to 1300mA or 1800mA and set 675 | + * the MPU voltage controller as needed. 676 | + */ 677 | + if (dpll_mpu_opp100.m == MPUPLL_M_1000) { 678 | + usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA; 679 | + mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV; 680 | + } else { 681 | + usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA; 682 | + mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV; 683 | + } 684 | + 685 | + if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, 686 | + TPS65217_POWER_PATH, 687 | + usb_cur_lim, 688 | + TPS65217_USB_INPUT_CUR_LIMIT_MASK)) 689 | + puts("tps65217_reg_write failure\n"); 690 | + 691 | + /* Set DCDC3 (CORE) voltage to 1.125V */ 692 | + if (tps65217_voltage_update(TPS65217_DEFDCDC3, 693 | + TPS65217_DCDC_VOLT_SEL_1125MV)) { 694 | + puts("tps65217_voltage_update failure\n"); 695 | + return; 696 | + } 697 | + 698 | + /* Set CORE Frequencies to OPP100 */ 699 | + do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); 700 | + 701 | + /* Set DCDC2 (MPU) voltage */ 702 | + if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) { 703 | + puts("tps65217_voltage_update failure\n"); 704 | + return; 705 | + } 706 | + 707 | + /* 708 | + * Set LDO3, LDO4 output voltage to 3.3V for Beaglebone. 709 | + * Set LDO3 to 1.8V and LDO4 to 3.3V for Beaglebone Black. 710 | + */ 711 | + if (board_is_bone()) { 712 | + if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, 713 | + TPS65217_DEFLS1, 714 | + TPS65217_LDO_VOLTAGE_OUT_3_3, 715 | + TPS65217_LDO_MASK)) 716 | + puts("tps65217_reg_write failure\n"); 717 | + } else { 718 | + if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, 719 | + TPS65217_DEFLS1, 720 | + TPS65217_LDO_VOLTAGE_OUT_1_8, 721 | + TPS65217_LDO_MASK)) 722 | + puts("tps65217_reg_write failure\n"); 723 | + } 724 | + 725 | + if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, 726 | + TPS65217_DEFLS2, 727 | + TPS65217_LDO_VOLTAGE_OUT_3_3, 728 | + TPS65217_LDO_MASK)) 729 | + puts("tps65217_reg_write failure\n"); 730 | + } else { 731 | + int sil_rev; 732 | + 733 | + /* 734 | + * The GP EVM, IDK and EVM SK use a TPS65910 PMIC. For all 735 | + * MPU frequencies we support we use a CORE voltage of 736 | + * 1.1375V. For MPU voltage we need to switch based on 737 | + * the frequency we are running at. 738 | + */ 739 | + if (i2c_probe(TPS65910_CTRL_I2C_ADDR)) 740 | + return; 741 | + 742 | + /* 743 | + * Depending on MPU clock and PG we will need a different 744 | + * VDD to drive at that speed. 745 | + */ 746 | + sil_rev = readl(&cdev->deviceid) >> 28; 747 | + mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev, 748 | + dpll_mpu_opp100.m); 749 | + 750 | + /* Tell the TPS65910 to use i2c */ 751 | + tps65910_set_i2c_control(); 752 | + 753 | + /* First update MPU voltage. */ 754 | + if (tps65910_voltage_update(MPU, mpu_vdd)) 755 | + return; 756 | + 757 | + /* Second, update the CORE voltage. */ 758 | + if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_3)) 759 | + return; 760 | + 761 | + /* Set CORE Frequencies to OPP100 */ 762 | + do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); 763 | + } 764 | + 765 | + /* Set MPU Frequency to what we detected now that voltages are set */ 766 | + do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); 767 | +} 768 | + 769 | +const struct dpll_params *get_dpll_ddr_params(void) 770 | +{ 771 | + if (board_is_evm_sk()) 772 | + return &dpll_ddr_evm_sk; 773 | + else if (board_is_bone_lt() || board_is_icev2()) 774 | + return &dpll_ddr_bone_black; 775 | + else if (board_is_evm_15_or_later()) 776 | + return &dpll_ddr_evm_sk; 777 | + else 778 | + return &dpll_ddr; 779 | +} 780 | + 781 | +void set_uart_mux_conf(void) 782 | +{ 783 | +#if CONFIG_CONS_INDEX == 1 784 | + enable_uart0_pin_mux(); 785 | +#elif CONFIG_CONS_INDEX == 2 786 | + enable_uart1_pin_mux(); 787 | +#elif CONFIG_CONS_INDEX == 3 788 | + enable_uart2_pin_mux(); 789 | +#elif CONFIG_CONS_INDEX == 4 790 | + enable_uart3_pin_mux(); 791 | +#elif CONFIG_CONS_INDEX == 5 792 | + enable_uart4_pin_mux(); 793 | +#elif CONFIG_CONS_INDEX == 6 794 | + enable_uart5_pin_mux(); 795 | +#endif 796 | +} 797 | + 798 | +void set_mux_conf_regs(void) 799 | +{ 800 | + enable_board_pin_mux(); 801 | +} 802 | + 803 | +const struct ctrl_ioregs ioregs_evmsk = { 804 | + .cm0ioctl = MT41J128MJT125_IOCTRL_VALUE, 805 | + .cm1ioctl = MT41J128MJT125_IOCTRL_VALUE, 806 | + .cm2ioctl = MT41J128MJT125_IOCTRL_VALUE, 807 | + .dt0ioctl = MT41J128MJT125_IOCTRL_VALUE, 808 | + .dt1ioctl = MT41J128MJT125_IOCTRL_VALUE, 809 | +}; 810 | + 811 | +const struct ctrl_ioregs ioregs_bonelt = { 812 | + .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 813 | + .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 814 | + .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 815 | + .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 816 | + .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 817 | +}; 818 | + 819 | +const struct ctrl_ioregs ioregs_evm15 = { 820 | + .cm0ioctl = MT41J512M8RH125_IOCTRL_VALUE, 821 | + .cm1ioctl = MT41J512M8RH125_IOCTRL_VALUE, 822 | + .cm2ioctl = MT41J512M8RH125_IOCTRL_VALUE, 823 | + .dt0ioctl = MT41J512M8RH125_IOCTRL_VALUE, 824 | + .dt1ioctl = MT41J512M8RH125_IOCTRL_VALUE, 825 | +}; 826 | + 827 | +const struct ctrl_ioregs ioregs = { 828 | + .cm0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, 829 | + .cm1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, 830 | + .cm2ioctl = MT47H128M16RT25E_IOCTRL_VALUE, 831 | + .dt0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, 832 | + .dt1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, 833 | +}; 834 | + 835 | +void sdram_init(void) 836 | +{ 837 | + if (board_is_evm_sk()) { 838 | + /* 839 | + * EVM SK 1.2A and later use gpio0_7 to enable DDR3. 840 | + * This is safe enough to do on older revs. 841 | + */ 842 | + gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en"); 843 | + gpio_direction_output(GPIO_DDR_VTT_EN, 1); 844 | + } 845 | + 846 | + if (board_is_icev2()) { 847 | + gpio_request(ICE_GPIO_DDR_VTT_EN, "ddr_vtt_en"); 848 | + gpio_direction_output(ICE_GPIO_DDR_VTT_EN, 1); 849 | + } 850 | + 851 | + if (board_is_evm_sk()) 852 | + config_ddr(303, &ioregs_evmsk, &ddr3_data, 853 | + &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0); 854 | + else if (board_is_bone_lt()) 855 | + config_ddr(400, &ioregs_bonelt, 856 | + &ddr3_beagleblack_data, 857 | + &ddr3_beagleblack_cmd_ctrl_data, 858 | + &ddr3_beagleblack_emif_reg_data, 0); 859 | + else if (board_is_evm_15_or_later()) 860 | + config_ddr(303, &ioregs_evm15, &ddr3_evm_data, 861 | + &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0); 862 | + else if (board_is_icev2()) 863 | + config_ddr(400, &ioregs_evmsk, &ddr3_icev2_data, 864 | + &ddr3_icev2_cmd_ctrl_data, &ddr3_icev2_emif_reg_data, 865 | + 0); 866 | + else if (board_is_gp_evm()) 867 | + config_ddr(266, &ioregs, &ddr2_data, 868 | + &ddr2_cmd_ctrl_data, &ddr2_evm_emif_reg_data, 0); 869 | + else 870 | + config_ddr(266, &ioregs, &ddr2_data, 871 | + &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0); 872 | +} 873 | +#endif 874 | + 875 | +#if !defined(CONFIG_SPL_BUILD) || \ 876 | + (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 877 | +static void request_and_set_gpio(int gpio, char *name, int val) 878 | +{ 879 | + int ret; 880 | + 881 | + ret = gpio_request(gpio, name); 882 | + if (ret < 0) { 883 | + printf("%s: Unable to request %s\n", __func__, name); 884 | + return; 885 | + } 886 | + 887 | + ret = gpio_direction_output(gpio, 0); 888 | + if (ret < 0) { 889 | + printf("%s: Unable to set %s as output\n", __func__, name); 890 | + goto err_free_gpio; 891 | + } 892 | + 893 | + gpio_set_value(gpio, val); 894 | + 895 | + return; 896 | + 897 | +err_free_gpio: 898 | + gpio_free(gpio); 899 | +} 900 | + 901 | +#define REQUEST_AND_SET_GPIO(N) request_and_set_gpio(N, #N, 1); 902 | +#define REQUEST_AND_CLR_GPIO(N) request_and_set_gpio(N, #N, 0); 903 | + 904 | +/** 905 | + * RMII mode on ICEv2 board needs 50MHz clock. Given the clock 906 | + * synthesizer With a capacitor of 18pF, and 25MHz input clock cycle 907 | + * PLL1 gives an output of 100MHz. So, configuring the div2/3 as 2 to 908 | + * give 50MHz output for Eth0 and 1. 909 | + */ 910 | +static struct clk_synth cdce913_data = { 911 | + .id = 0x81, 912 | + .capacitor = 0x90, 913 | + .mux = 0x6d, 914 | + .pdiv2 = 0x2, 915 | + .pdiv3 = 0x2, 916 | +}; 917 | +#endif 918 | + 919 | +/* 920 | + * Basic board specific setup. Pinmux has been handled already. 921 | + */ 922 | +int board_init(void) 923 | +{ 924 | +#if defined(CONFIG_HW_WATCHDOG) 925 | + hw_watchdog_init(); 926 | +#endif 927 | + 928 | + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 929 | +#if defined(CONFIG_NOR) || defined(CONFIG_NAND) 930 | + gpmc_init(); 931 | +#endif 932 | + 933 | +#if !defined(CONFIG_SPL_BUILD) || \ 934 | + (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 935 | + if (board_is_icev2()) { 936 | + int rv; 937 | + u32 reg; 938 | + 939 | + REQUEST_AND_SET_GPIO(GPIO_PR1_MII_CTRL); 940 | + /* Make J19 status available on GPIO1_26 */ 941 | + REQUEST_AND_CLR_GPIO(GPIO_MUX_MII_CTRL); 942 | + 943 | + REQUEST_AND_SET_GPIO(GPIO_FET_SWITCH_CTRL); 944 | + /* 945 | + * Both ports can be set as RMII-CPSW or MII-PRU-ETH using 946 | + * jumpers near the port. Read the jumper value and set 947 | + * the pinmux, external mux and PHY clock accordingly. 948 | + * As jumper line is overridden by PHY RX_DV pin immediately 949 | + * after bootstrap (power-up/reset), we need to sample 950 | + * it during PHY reset using GPIO rising edge detection. 951 | + */ 952 | + REQUEST_AND_SET_GPIO(GPIO_PHY_RESET); 953 | + /* Enable rising edge IRQ on GPIO0_11 and GPIO 1_26 */ 954 | + reg = readl(GPIO0_RISINGDETECT) | BIT(11); 955 | + writel(reg, GPIO0_RISINGDETECT); 956 | + reg = readl(GPIO1_RISINGDETECT) | BIT(26); 957 | + writel(reg, GPIO1_RISINGDETECT); 958 | + /* Reset PHYs to capture the Jumper setting */ 959 | + gpio_set_value(GPIO_PHY_RESET, 0); 960 | + udelay(2); /* PHY datasheet states 1uS min. */ 961 | + gpio_set_value(GPIO_PHY_RESET, 1); 962 | + 963 | + reg = readl(GPIO0_IRQSTATUSRAW) & BIT(11); 964 | + if (reg) { 965 | + writel(reg, GPIO0_IRQSTATUS1); /* clear irq */ 966 | + /* RMII mode */ 967 | + printf("ETH0, CPSW\n"); 968 | + } else { 969 | + /* MII mode */ 970 | + printf("ETH0, PRU\n"); 971 | + cdce913_data.pdiv3 = 4; /* 25MHz PHY clk */ 972 | + } 973 | + 974 | + reg = readl(GPIO1_IRQSTATUSRAW) & BIT(26); 975 | + if (reg) { 976 | + writel(reg, GPIO1_IRQSTATUS1); /* clear irq */ 977 | + /* RMII mode */ 978 | + printf("ETH1, CPSW\n"); 979 | + gpio_set_value(GPIO_MUX_MII_CTRL, 1); 980 | + } else { 981 | + /* MII mode */ 982 | + printf("ETH1, PRU\n"); 983 | + cdce913_data.pdiv2 = 4; /* 25MHz PHY clk */ 984 | + } 985 | + 986 | + /* disable rising edge IRQs */ 987 | + reg = readl(GPIO0_RISINGDETECT) & ~BIT(11); 988 | + writel(reg, GPIO0_RISINGDETECT); 989 | + reg = readl(GPIO1_RISINGDETECT) & ~BIT(26); 990 | + writel(reg, GPIO1_RISINGDETECT); 991 | + 992 | + rv = setup_clock_synthesizer(&cdce913_data); 993 | + if (rv) { 994 | + printf("Clock synthesizer setup failed %d\n", rv); 995 | + return rv; 996 | + } 997 | + 998 | + /* reset PHYs */ 999 | + gpio_set_value(GPIO_PHY_RESET, 0); 1000 | + udelay(2); /* PHY datasheet states 1uS min. */ 1001 | + gpio_set_value(GPIO_PHY_RESET, 1); 1002 | + } 1003 | +#endif 1004 | + 1005 | + return 0; 1006 | +} 1007 | + 1008 | +#ifdef CONFIG_BOARD_LATE_INIT 1009 | +int board_late_init(void) 1010 | +{ 1011 | +#if !defined(CONFIG_SPL_BUILD) 1012 | + uint8_t mac_addr[6]; 1013 | + uint32_t mac_hi, mac_lo; 1014 | +#endif 1015 | + 1016 | +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 1017 | + char *name = NULL; 1018 | + 1019 | + if (board_is_bbg1()) 1020 | + name = "BBG1"; 1021 | + set_board_info_env(name); 1022 | + 1023 | + /* 1024 | + * Default FIT boot on HS devices. Non FIT images are not allowed 1025 | + * on HS devices. 1026 | + */ 1027 | + if (get_device_type() == HS_DEVICE) 1028 | + setenv("boot_fit", "1"); 1029 | +#endif 1030 | + 1031 | +#if !defined(CONFIG_SPL_BUILD) 1032 | + /* try reading mac address from efuse */ 1033 | + mac_lo = readl(&cdev->macid0l); 1034 | + mac_hi = readl(&cdev->macid0h); 1035 | + mac_addr[0] = mac_hi & 0xFF; 1036 | + mac_addr[1] = (mac_hi & 0xFF00) >> 8; 1037 | + mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 1038 | + mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 1039 | + mac_addr[4] = mac_lo & 0xFF; 1040 | + mac_addr[5] = (mac_lo & 0xFF00) >> 8; 1041 | + 1042 | + if (!getenv("ethaddr")) { 1043 | + printf(" not set. Validating first E-fuse MAC\n"); 1044 | + 1045 | + if (is_valid_ethaddr(mac_addr)) 1046 | + eth_setenv_enetaddr("ethaddr", mac_addr); 1047 | + } 1048 | + 1049 | + mac_lo = readl(&cdev->macid1l); 1050 | + mac_hi = readl(&cdev->macid1h); 1051 | + mac_addr[0] = mac_hi & 0xFF; 1052 | + mac_addr[1] = (mac_hi & 0xFF00) >> 8; 1053 | + mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 1054 | + mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 1055 | + mac_addr[4] = mac_lo & 0xFF; 1056 | + mac_addr[5] = (mac_lo & 0xFF00) >> 8; 1057 | + 1058 | + if (!getenv("eth1addr")) { 1059 | + if (is_valid_ethaddr(mac_addr)) 1060 | + eth_setenv_enetaddr("eth1addr", mac_addr); 1061 | + } 1062 | +#endif 1063 | + 1064 | + return 0; 1065 | +} 1066 | +#endif 1067 | + 1068 | +#ifndef CONFIG_DM_ETH 1069 | + 1070 | +#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 1071 | + (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 1072 | +static void cpsw_control(int enabled) 1073 | +{ 1074 | + /* VTP can be added here */ 1075 | + 1076 | + return; 1077 | +} 1078 | + 1079 | +static struct cpsw_slave_data cpsw_slaves[] = { 1080 | + { 1081 | + .slave_reg_ofs = 0x208, 1082 | + .sliver_reg_ofs = 0xd80, 1083 | + .phy_addr = 0, 1084 | + }, 1085 | + { 1086 | + .slave_reg_ofs = 0x308, 1087 | + .sliver_reg_ofs = 0xdc0, 1088 | + .phy_addr = 1, 1089 | + }, 1090 | +}; 1091 | + 1092 | +static struct cpsw_platform_data cpsw_data = { 1093 | + .mdio_base = CPSW_MDIO_BASE, 1094 | + .cpsw_base = CPSW_BASE, 1095 | + .mdio_div = 0xff, 1096 | + .channels = 8, 1097 | + .cpdma_reg_ofs = 0x800, 1098 | + .slaves = 1, 1099 | + .slave_data = cpsw_slaves, 1100 | + .ale_reg_ofs = 0xd00, 1101 | + .ale_entries = 1024, 1102 | + .host_port_reg_ofs = 0x108, 1103 | + .hw_stats_reg_ofs = 0x900, 1104 | + .bd_ram_ofs = 0x2000, 1105 | + .mac_control = (1 << 5), 1106 | + .control = cpsw_control, 1107 | + .host_port_num = 0, 1108 | + .version = CPSW_CTRL_VERSION_2, 1109 | +}; 1110 | +#endif 1111 | + 1112 | +#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)) &&\ 1113 | + defined(CONFIG_SPL_BUILD)) || \ 1114 | + ((defined(CONFIG_DRIVER_TI_CPSW) || \ 1115 | + defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) && \ 1116 | + !defined(CONFIG_SPL_BUILD)) 1117 | + 1118 | +/* 1119 | + * This function will: 1120 | + * Read the eFuse for MAC addresses, and set ethaddr/eth1addr/usbnet_devaddr 1121 | + * in the environment 1122 | + * Perform fixups to the PHY present on certain boards. We only need this 1123 | + * function in: 1124 | + * - SPL with either CPSW or USB ethernet support 1125 | + * - Full U-Boot, with either CPSW or USB ethernet 1126 | + * Build in only these cases to avoid warnings about unused variables 1127 | + * when we build an SPL that has neither option but full U-Boot will. 1128 | + */ 1129 | +int board_eth_init(bd_t *bis) 1130 | +{ 1131 | + int rv, n = 0; 1132 | +#if defined(CONFIG_USB_ETHER) && \ 1133 | + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT)) 1134 | + uint8_t mac_addr[6]; 1135 | + uint32_t mac_hi, mac_lo; 1136 | + 1137 | + /* 1138 | + * use efuse mac address for USB ethernet as we know that 1139 | + * both CPSW and USB ethernet will never be active at the same time 1140 | + */ 1141 | + mac_lo = readl(&cdev->macid0l); 1142 | + mac_hi = readl(&cdev->macid0h); 1143 | + mac_addr[0] = mac_hi & 0xFF; 1144 | + mac_addr[1] = (mac_hi & 0xFF00) >> 8; 1145 | + mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 1146 | + mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 1147 | + mac_addr[4] = mac_lo & 0xFF; 1148 | + mac_addr[5] = (mac_lo & 0xFF00) >> 8; 1149 | +#endif 1150 | + 1151 | + 1152 | +#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ 1153 | + (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) 1154 | + 1155 | +#ifdef CONFIG_DRIVER_TI_CPSW 1156 | + if (board_is_bone() || board_is_bone_lt() || 1157 | + board_is_idk()) { 1158 | + writel(MII_MODE_ENABLE, &cdev->miisel); 1159 | + cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if = 1160 | + PHY_INTERFACE_MODE_MII; 1161 | + } else if (board_is_icev2()) { 1162 | + writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel); 1163 | + cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII; 1164 | + cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RMII; 1165 | + cpsw_slaves[0].phy_addr = 1; 1166 | + cpsw_slaves[1].phy_addr = 3; 1167 | + } else { 1168 | + writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel); 1169 | + cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if = 1170 | + PHY_INTERFACE_MODE_RGMII; 1171 | + } 1172 | + 1173 | + rv = cpsw_register(&cpsw_data); 1174 | + if (rv < 0) 1175 | + printf("Error %d registering CPSW switch\n", rv); 1176 | + else 1177 | + n += rv; 1178 | +#endif 1179 | + 1180 | + /* 1181 | + * 1182 | + * CPSW RGMII Internal Delay Mode is not supported in all PVT 1183 | + * operating points. So we must set the TX clock delay feature 1184 | + * in the AR8051 PHY. Since we only support a single ethernet 1185 | + * device in U-Boot, we only do this for the first instance. 1186 | + */ 1187 | +#define AR8051_PHY_DEBUG_ADDR_REG 0x1d 1188 | +#define AR8051_PHY_DEBUG_DATA_REG 0x1e 1189 | +#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5 1190 | +#define AR8051_RGMII_TX_CLK_DLY 0x100 1191 | + 1192 | + if (board_is_evm_sk() || board_is_gp_evm()) { 1193 | + const char *devname; 1194 | + devname = miiphy_get_current_dev(); 1195 | + 1196 | + miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG, 1197 | + AR8051_DEBUG_RGMII_CLK_DLY_REG); 1198 | + miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG, 1199 | + AR8051_RGMII_TX_CLK_DLY); 1200 | + } 1201 | +#endif 1202 | +#if defined(CONFIG_USB_ETHER) && \ 1203 | + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT)) 1204 | + if (is_valid_ethaddr(mac_addr)) 1205 | + eth_setenv_enetaddr("usbnet_devaddr", mac_addr); 1206 | + 1207 | + rv = usb_eth_initialize(bis); 1208 | + if (rv < 0) 1209 | + printf("Error %d registering USB_ETHER\n", rv); 1210 | + else 1211 | + n += rv; 1212 | +#endif 1213 | + return n; 1214 | +} 1215 | +#endif 1216 | + 1217 | +#endif /* CONFIG_DM_ETH */ 1218 | + 1219 | +#ifdef CONFIG_SPL_LOAD_FIT 1220 | +int board_fit_config_name_match(const char *name) 1221 | +{ 1222 | + if (board_is_gp_evm() && !strcmp(name, "am335x-evm")) 1223 | + return 0; 1224 | + else if (board_is_bone() && !strcmp(name, "am335x-bone")) 1225 | + return 0; 1226 | + else if (board_is_bone_lt() && !strcmp(name, "am335x-boneblack")) 1227 | + return 0; 1228 | + else if (board_is_evm_sk() && !strcmp(name, "am335x-evmsk")) 1229 | + return 0; 1230 | + else if (board_is_bbg1() && !strcmp(name, "am335x-bonegreen")) 1231 | + return 0; 1232 | + else if (board_is_icev2() && !strcmp(name, "am335x-icev2")) 1233 | + return 0; 1234 | + else 1235 | + return -1; 1236 | +} 1237 | +#endif 1238 | + 1239 | +#ifdef CONFIG_TI_SECURE_DEVICE 1240 | +void board_fit_image_post_process(void **p_image, size_t *p_size) 1241 | +{ 1242 | + secure_boot_verify_image(p_image, p_size); 1243 | +} 1244 | +#endif 1245 | diff --git a/board/ti/nova/board.h b/board/ti/nova/board.h 1246 | new file mode 100644 1247 | index 0000000..48c139a 1248 | --- /dev/null 1249 | +++ b/board/ti/nova/board.h 1250 | @@ -0,0 +1,82 @@ 1251 | +/* 1252 | + * board.h 1253 | + * 1254 | + * TI AM335x boards information header 1255 | + * 1256 | + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ 1257 | + * 1258 | + * SPDX-License-Identifier: GPL-2.0+ 1259 | + */ 1260 | + 1261 | +#ifndef _BOARD_H_ 1262 | +#define _BOARD_H_ 1263 | + 1264 | +/** 1265 | + * AM335X (EMIF_4D) EMIF REG_COS_COUNT_1, REG_COS_COUNT_2, and 1266 | + * REG_PR_OLD_COUNT values to avoid LCDC DMA FIFO underflows and Frame 1267 | + * Synchronization Lost errors. The values are the biggest that work 1268 | + * reliably with offered video modes and the memory subsystem on the 1269 | + * boards. These register have are briefly documented in "7.3.3.5.2 1270 | + * Command Starvation" section of AM335x TRM. The REG_COS_COUNT_1 and 1271 | + * REG_COS_COUNT_2 do not have any effect on current versions of 1272 | + * AM335x. 1273 | + */ 1274 | +#define EMIF_OCP_CONFIG_BEAGLEBONE_BLACK 0x00141414 1275 | +#define EMIF_OCP_CONFIG_AM335X_EVM 0x003d3d3d 1276 | + 1277 | +static inline int board_is_bone(void) 1278 | +{ 1279 | + return board_ti_is("A335BONE"); 1280 | +} 1281 | + 1282 | +static inline int board_is_bone_lt(void) 1283 | +{ 1284 | + return board_ti_is("A335BNLT"); 1285 | +} 1286 | + 1287 | +static inline int board_is_bbg1(void) 1288 | +{ 1289 | + return board_is_bone_lt() && !strncmp(board_ti_get_rev(), "BBG1", 4); 1290 | +} 1291 | + 1292 | +static inline int board_is_evm_sk(void) 1293 | +{ 1294 | + return board_ti_is("A335X_SK"); 1295 | +} 1296 | + 1297 | +static inline int board_is_idk(void) 1298 | +{ 1299 | + return !strncmp(board_ti_get_config(), "SKU#02", 6); 1300 | +} 1301 | + 1302 | +static inline int board_is_gp_evm(void) 1303 | +{ 1304 | + return board_ti_is("A33515BB"); 1305 | +} 1306 | + 1307 | +static inline int board_is_evm_15_or_later(void) 1308 | +{ 1309 | + return (board_is_gp_evm() && 1310 | + strncmp("1.5", board_ti_get_rev(), 3) <= 0); 1311 | +} 1312 | + 1313 | +static inline int board_is_icev2(void) 1314 | +{ 1315 | + return board_ti_is("A335_ICE") && !strncmp("2", board_ti_get_rev(), 1); 1316 | +} 1317 | + 1318 | +/* 1319 | + * We have three pin mux functions that must exist. We must be able to enable 1320 | + * uart0, for initial output and i2c0 to read the main EEPROM. We then have a 1321 | + * main pinmux function that can be overridden to enable all other pinmux that 1322 | + * is required on the board. 1323 | + */ 1324 | +void enable_uart0_pin_mux(void); 1325 | +void enable_uart1_pin_mux(void); 1326 | +void enable_uart2_pin_mux(void); 1327 | +void enable_uart3_pin_mux(void); 1328 | +void enable_uart4_pin_mux(void); 1329 | +void enable_uart5_pin_mux(void); 1330 | +void enable_i2c0_pin_mux(void); 1331 | +void enable_board_pin_mux(void); 1332 | +#endif 1333 | diff --git a/board/ti/nova/mux.c b/board/ti/nova/mux.c 1334 | new file mode 100644 1335 | index 0000000..ad85b3a 1336 | --- /dev/null 1337 | +++ b/board/ti/nova/mux.c 1338 | @@ -0,0 +1,403 @@ 1339 | +/* 1340 | + * mux.c 1341 | + * 1342 | + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 1343 | + * 1344 | + * This program is free software; you can redistribute it and/or 1345 | + * modify it under the terms of the GNU General Public License as 1346 | + * published by the Free Software Foundation version 2. 1347 | + * 1348 | + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 1349 | + * kind, whether express or implied; without even the implied warranty 1350 | + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1351 | + * GNU General Public License for more details. 1352 | + */ 1353 | + 1354 | +#include 1355 | +#include 1356 | +#include 1357 | +#include 1358 | +#include 1359 | +#include 1360 | +#include "../common/board_detect.h" 1361 | +#include "board.h" 1362 | + 1363 | +static struct module_pin_mux uart0_pin_mux[] = { 1364 | + {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */ 1365 | + {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, /* UART0_TXD */ 1366 | + {-1}, 1367 | +}; 1368 | + 1369 | +static struct module_pin_mux uart1_pin_mux[] = { 1370 | + {OFFSET(uart1_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART1_RXD */ 1371 | + {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, /* UART1_TXD */ 1372 | + {-1}, 1373 | +}; 1374 | + 1375 | +static struct module_pin_mux uart2_pin_mux[] = { 1376 | + {OFFSET(spi0_sclk), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART2_RXD */ 1377 | + {OFFSET(spi0_d0), (MODE(1) | PULLUDEN)}, /* UART2_TXD */ 1378 | + {-1}, 1379 | +}; 1380 | + 1381 | +static struct module_pin_mux uart3_pin_mux[] = { 1382 | + {OFFSET(spi0_cs1), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART3_RXD */ 1383 | + {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */ 1384 | + {-1}, 1385 | +}; 1386 | + 1387 | +static struct module_pin_mux uart4_pin_mux[] = { 1388 | + {OFFSET(gpmc_wait0), (MODE(6) | PULLUP_EN | RXACTIVE)}, /* UART4_RXD */ 1389 | + {OFFSET(gpmc_wpn), (MODE(6) | PULLUDEN)}, /* UART4_TXD */ 1390 | + {-1}, 1391 | +}; 1392 | + 1393 | +static struct module_pin_mux uart5_pin_mux[] = { 1394 | + {OFFSET(lcd_data9), (MODE(4) | PULLUP_EN | RXACTIVE)}, /* UART5_RXD */ 1395 | + {OFFSET(lcd_data8), (MODE(4) | PULLUDEN)}, /* UART5_TXD */ 1396 | + {-1}, 1397 | +}; 1398 | + 1399 | +static struct module_pin_mux mmc0_pin_mux[] = { 1400 | + {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */ 1401 | + {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */ 1402 | + {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */ 1403 | + {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */ 1404 | + {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */ 1405 | + {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */ 1406 | + {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */ 1407 | + {OFFSET(spi0_cs1), (MODE(7) | RXACTIVE | PULLUP_EN)}, /* GPIO0_6 */ 1408 | + {-1}, 1409 | +}; 1410 | + 1411 | +static struct module_pin_mux mmc0_no_cd_pin_mux[] = { 1412 | + {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */ 1413 | + {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */ 1414 | + {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */ 1415 | + {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */ 1416 | + {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */ 1417 | + {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */ 1418 | + {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */ 1419 | + {-1}, 1420 | +}; 1421 | + 1422 | +static struct module_pin_mux mmc0_pin_mux_sk_evm[] = { 1423 | + {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */ 1424 | + {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */ 1425 | + {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */ 1426 | + {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */ 1427 | + {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */ 1428 | + {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */ 1429 | + {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */ 1430 | + {-1}, 1431 | +}; 1432 | + 1433 | +static struct module_pin_mux mmc1_pin_mux[] = { 1434 | + {OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT3 */ 1435 | + {OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT2 */ 1436 | + {OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT1 */ 1437 | + {OFFSET(gpmc_ad0), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT0 */ 1438 | + {OFFSET(gpmc_csn1), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CLK */ 1439 | + {OFFSET(gpmc_csn2), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CMD */ 1440 | + {OFFSET(gpmc_csn0), (MODE(7) | RXACTIVE | PULLUP_EN)}, /* MMC1_WP */ 1441 | + {OFFSET(gpmc_advn_ale), (MODE(7) | RXACTIVE | PULLUP_EN)}, /* MMC1_CD */ 1442 | + {-1}, 1443 | +}; 1444 | + 1445 | +static struct module_pin_mux i2c0_pin_mux[] = { 1446 | + {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | 1447 | + PULLUDEN | SLEWCTRL)}, /* I2C_DATA */ 1448 | + {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | 1449 | + PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */ 1450 | + {-1}, 1451 | +}; 1452 | + 1453 | +static struct module_pin_mux i2c1_pin_mux[] = { 1454 | + {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | 1455 | + PULLUDEN | SLEWCTRL)}, /* I2C_DATA */ 1456 | + {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | 1457 | + PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */ 1458 | + {-1}, 1459 | +}; 1460 | + 1461 | +static struct module_pin_mux spi0_pin_mux[] = { 1462 | + {OFFSET(spi0_sclk), (MODE(0) | RXACTIVE | PULLUDEN)}, /* SPI0_SCLK */ 1463 | + {OFFSET(spi0_d0), (MODE(0) | RXACTIVE | 1464 | + PULLUDEN | PULLUP_EN)}, /* SPI0_D0 */ 1465 | + {OFFSET(spi0_d1), (MODE(0) | RXACTIVE | PULLUDEN)}, /* SPI0_D1 */ 1466 | + {OFFSET(spi0_cs0), (MODE(0) | RXACTIVE | 1467 | + PULLUDEN | PULLUP_EN)}, /* SPI0_CS0 */ 1468 | + {-1}, 1469 | +}; 1470 | + 1471 | +static struct module_pin_mux gpio0_7_pin_mux[] = { 1472 | + {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN)}, /* GPIO0_7 */ 1473 | + {-1}, 1474 | +}; 1475 | + 1476 | +static struct module_pin_mux gpio0_18_pin_mux[] = { 1477 | + {OFFSET(usb0_drvvbus), (MODE(7) | PULLUDEN)}, /* GPIO0_18 */ 1478 | + {-1}, 1479 | +}; 1480 | + 1481 | +static struct module_pin_mux rgmii1_pin_mux[] = { 1482 | + {OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */ 1483 | + {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */ 1484 | + {OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */ 1485 | + {OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */ 1486 | + {OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */ 1487 | + {OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */ 1488 | + {OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */ 1489 | + {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */ 1490 | + {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */ 1491 | + {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */ 1492 | + {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */ 1493 | + {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */ 1494 | + {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN},/* MDIO_DATA */ 1495 | + {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ 1496 | + {-1}, 1497 | +}; 1498 | + 1499 | +static struct module_pin_mux mii1_pin_mux[] = { 1500 | + {OFFSET(mii1_rxerr), MODE(0) | RXACTIVE}, /* MII1_RXERR */ 1501 | + {OFFSET(mii1_txen), MODE(0)}, /* MII1_TXEN */ 1502 | + {OFFSET(mii1_rxdv), MODE(0) | RXACTIVE}, /* MII1_RXDV */ 1503 | + {OFFSET(mii1_txd3), MODE(0)}, /* MII1_TXD3 */ 1504 | + {OFFSET(mii1_txd2), MODE(0)}, /* MII1_TXD2 */ 1505 | + {OFFSET(mii1_txd1), MODE(0)}, /* MII1_TXD1 */ 1506 | + {OFFSET(mii1_txd0), MODE(0)}, /* MII1_TXD0 */ 1507 | + {OFFSET(mii1_txclk), MODE(0) | RXACTIVE}, /* MII1_TXCLK */ 1508 | + {OFFSET(mii1_rxclk), MODE(0) | RXACTIVE}, /* MII1_RXCLK */ 1509 | + {OFFSET(mii1_rxd3), MODE(0) | RXACTIVE}, /* MII1_RXD3 */ 1510 | + {OFFSET(mii1_rxd2), MODE(0) | RXACTIVE}, /* MII1_RXD2 */ 1511 | + {OFFSET(mii1_rxd1), MODE(0) | RXACTIVE}, /* MII1_RXD1 */ 1512 | + {OFFSET(mii1_rxd0), MODE(0) | RXACTIVE}, /* MII1_RXD0 */ 1513 | + {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */ 1514 | + {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ 1515 | + {-1}, 1516 | +}; 1517 | + 1518 | +static struct module_pin_mux rmii1_pin_mux[] = { 1519 | + {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ 1520 | + {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */ 1521 | + {OFFSET(mii1_crs), MODE(1) | RXACTIVE}, /* MII1_CRS */ 1522 | + {OFFSET(mii1_rxerr), MODE(1) | RXACTIVE}, /* MII1_RXERR */ 1523 | + {OFFSET(mii1_txen), MODE(1)}, /* MII1_TXEN */ 1524 | + {OFFSET(mii1_txd1), MODE(1)}, /* MII1_TXD1 */ 1525 | + {OFFSET(mii1_txd0), MODE(1)}, /* MII1_TXD0 */ 1526 | + {OFFSET(mii1_rxd1), MODE(1) | RXACTIVE}, /* MII1_RXD1 */ 1527 | + {OFFSET(mii1_rxd0), MODE(1) | RXACTIVE}, /* MII1_RXD0 */ 1528 | + {OFFSET(rmii1_refclk), MODE(0) | RXACTIVE}, /* RMII1_REFCLK */ 1529 | + {-1}, 1530 | +}; 1531 | + 1532 | +#ifdef CONFIG_NAND 1533 | +static struct module_pin_mux nand_pin_mux[] = { 1534 | + {OFFSET(gpmc_ad0), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD0 */ 1535 | + {OFFSET(gpmc_ad1), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD1 */ 1536 | + {OFFSET(gpmc_ad2), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD2 */ 1537 | + {OFFSET(gpmc_ad3), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD3 */ 1538 | + {OFFSET(gpmc_ad4), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD4 */ 1539 | + {OFFSET(gpmc_ad5), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD5 */ 1540 | + {OFFSET(gpmc_ad6), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD6 */ 1541 | + {OFFSET(gpmc_ad7), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD7 */ 1542 | +#ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT 1543 | + {OFFSET(gpmc_ad8), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD8 */ 1544 | + {OFFSET(gpmc_ad9), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD9 */ 1545 | + {OFFSET(gpmc_ad10), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD10 */ 1546 | + {OFFSET(gpmc_ad11), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD11 */ 1547 | + {OFFSET(gpmc_ad12), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD12 */ 1548 | + {OFFSET(gpmc_ad13), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD13 */ 1549 | + {OFFSET(gpmc_ad14), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD14 */ 1550 | + {OFFSET(gpmc_ad15), (MODE(0) | PULLUDDIS | RXACTIVE)}, /* AD15 */ 1551 | +#endif 1552 | + {OFFSET(gpmc_wait0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* nWAIT */ 1553 | + {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN)}, /* nWP */ 1554 | + {OFFSET(gpmc_csn0), (MODE(0) | PULLUP_EN)}, /* nCS */ 1555 | + {OFFSET(gpmc_wen), (MODE(0) | PULLDOWN_EN)}, /* WEN */ 1556 | + {OFFSET(gpmc_oen_ren), (MODE(0) | PULLDOWN_EN)}, /* OE */ 1557 | + {OFFSET(gpmc_advn_ale), (MODE(0) | PULLDOWN_EN)}, /* ADV_ALE */ 1558 | + {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLDOWN_EN)}, /* BE_CLE */ 1559 | + {-1}, 1560 | +}; 1561 | +#elif defined(CONFIG_NOR) 1562 | +static struct module_pin_mux bone_norcape_pin_mux[] = { 1563 | + {OFFSET(gpmc_a0), MODE(0) | PULLUDDIS}, /* NOR_A0 */ 1564 | + {OFFSET(gpmc_a1), MODE(0) | PULLUDDIS}, /* NOR_A1 */ 1565 | + {OFFSET(gpmc_a2), MODE(0) | PULLUDDIS}, /* NOR_A2 */ 1566 | + {OFFSET(gpmc_a3), MODE(0) | PULLUDDIS}, /* NOR_A3 */ 1567 | + {OFFSET(gpmc_a4), MODE(0) | PULLUDDIS}, /* NOR_A4 */ 1568 | + {OFFSET(gpmc_a5), MODE(0) | PULLUDDIS}, /* NOR_A5 */ 1569 | + {OFFSET(gpmc_a6), MODE(0) | PULLUDDIS}, /* NOR_A6 */ 1570 | + {OFFSET(gpmc_a7), MODE(0) | PULLUDDIS}, /* NOR_A7 */ 1571 | + {OFFSET(gpmc_ad0), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD0 */ 1572 | + {OFFSET(gpmc_ad1), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD1 */ 1573 | + {OFFSET(gpmc_ad2), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD2 */ 1574 | + {OFFSET(gpmc_ad3), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD3 */ 1575 | + {OFFSET(gpmc_ad4), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD4 */ 1576 | + {OFFSET(gpmc_ad5), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD5 */ 1577 | + {OFFSET(gpmc_ad6), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD6 */ 1578 | + {OFFSET(gpmc_ad7), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD7 */ 1579 | + {OFFSET(gpmc_ad8), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD8 */ 1580 | + {OFFSET(gpmc_ad9), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD9 */ 1581 | + {OFFSET(gpmc_ad10), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD10 */ 1582 | + {OFFSET(gpmc_ad11), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD11 */ 1583 | + {OFFSET(gpmc_ad12), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD12 */ 1584 | + {OFFSET(gpmc_ad13), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD13 */ 1585 | + {OFFSET(gpmc_ad14), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD14 */ 1586 | + {OFFSET(gpmc_ad15), MODE(0) | PULLUDDIS | RXACTIVE}, /* NOR_AD15 */ 1587 | + {OFFSET(gpmc_csn0), MODE(0) | PULLUDEN | PULLUP_EN}, /* CE */ 1588 | + {OFFSET(gpmc_advn_ale), MODE(0) | PULLUDEN | PULLDOWN_EN}, /* ALE */ 1589 | + {OFFSET(gpmc_oen_ren), MODE(0) | PULLUDEN | PULLDOWN_EN},/* OEn_REN */ 1590 | + {OFFSET(gpmc_be0n_cle), MODE(0) | PULLUDEN | PULLDOWN_EN},/* unused */ 1591 | + {OFFSET(gpmc_wen), MODE(0) | PULLUDEN | PULLDOWN_EN}, /* WEN */ 1592 | + {OFFSET(gpmc_wait0), MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE},/*WAIT*/ 1593 | + {-1}, 1594 | +}; 1595 | +#endif 1596 | + 1597 | +static struct module_pin_mux uart3_icev2_pin_mux[] = { 1598 | + {OFFSET(mii1_rxd3), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART3_RXD */ 1599 | + {OFFSET(mii1_rxd2), MODE(1) | PULLUDEN}, /* UART3_TXD */ 1600 | + {-1}, 1601 | +}; 1602 | + 1603 | +#if defined(CONFIG_NOR_BOOT) 1604 | +void enable_norboot_pin_mux(void) 1605 | +{ 1606 | + configure_module_pin_mux(bone_norcape_pin_mux); 1607 | +} 1608 | +#endif 1609 | + 1610 | +void enable_uart0_pin_mux(void) 1611 | +{ 1612 | + configure_module_pin_mux(uart0_pin_mux); 1613 | +} 1614 | + 1615 | +void enable_uart1_pin_mux(void) 1616 | +{ 1617 | + configure_module_pin_mux(uart1_pin_mux); 1618 | +} 1619 | + 1620 | +void enable_uart2_pin_mux(void) 1621 | +{ 1622 | + configure_module_pin_mux(uart2_pin_mux); 1623 | +} 1624 | + 1625 | +void enable_uart3_pin_mux(void) 1626 | +{ 1627 | + configure_module_pin_mux(uart3_pin_mux); 1628 | +} 1629 | + 1630 | +void enable_uart4_pin_mux(void) 1631 | +{ 1632 | + configure_module_pin_mux(uart4_pin_mux); 1633 | +} 1634 | + 1635 | +void enable_uart5_pin_mux(void) 1636 | +{ 1637 | + configure_module_pin_mux(uart5_pin_mux); 1638 | +} 1639 | + 1640 | +void enable_i2c0_pin_mux(void) 1641 | +{ 1642 | + configure_module_pin_mux(i2c0_pin_mux); 1643 | +} 1644 | + 1645 | +/* 1646 | + * The AM335x GP EVM, if daughter card(s) are connected, can have 8 1647 | + * different profiles. These profiles determine what peripherals are 1648 | + * valid and need pinmux to be configured. 1649 | + */ 1650 | +#define PROFILE_NONE 0x0 1651 | +#define PROFILE_0 (1 << 0) 1652 | +#define PROFILE_1 (1 << 1) 1653 | +#define PROFILE_2 (1 << 2) 1654 | +#define PROFILE_3 (1 << 3) 1655 | +#define PROFILE_4 (1 << 4) 1656 | +#define PROFILE_5 (1 << 5) 1657 | +#define PROFILE_6 (1 << 6) 1658 | +#define PROFILE_7 (1 << 7) 1659 | +#define PROFILE_MASK 0x7 1660 | +#define PROFILE_ALL 0xFF 1661 | + 1662 | +/* CPLD registers */ 1663 | +#define I2C_CPLD_ADDR 0x35 1664 | +#define CFG_REG 0x10 1665 | + 1666 | +static unsigned short detect_daughter_board_profile(void) 1667 | +{ 1668 | + unsigned short val; 1669 | + 1670 | + if (i2c_probe(I2C_CPLD_ADDR)) 1671 | + return PROFILE_NONE; 1672 | + 1673 | + if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2)) 1674 | + return PROFILE_NONE; 1675 | + 1676 | + return (1 << (val & PROFILE_MASK)); 1677 | +} 1678 | + 1679 | +void enable_board_pin_mux(void) 1680 | +{ 1681 | + /* Do board-specific muxes. */ 1682 | + if (board_is_bone()) { 1683 | + /* Beaglebone pinmux */ 1684 | + configure_module_pin_mux(mii1_pin_mux); 1685 | + configure_module_pin_mux(mmc0_pin_mux); 1686 | +#if defined(CONFIG_NAND) 1687 | + configure_module_pin_mux(nand_pin_mux); 1688 | +#elif defined(CONFIG_NOR) 1689 | + configure_module_pin_mux(bone_norcape_pin_mux); 1690 | +#else 1691 | + configure_module_pin_mux(mmc1_pin_mux); 1692 | +#endif 1693 | + } else if (board_is_gp_evm()) { 1694 | + /* General Purpose EVM */ 1695 | + unsigned short profile = detect_daughter_board_profile(); 1696 | + configure_module_pin_mux(rgmii1_pin_mux); 1697 | + configure_module_pin_mux(mmc0_pin_mux); 1698 | + /* In profile #2 i2c1 and spi0 conflict. */ 1699 | + if (profile & ~PROFILE_2) 1700 | + configure_module_pin_mux(i2c1_pin_mux); 1701 | + /* Profiles 2 & 3 don't have NAND */ 1702 | +#ifdef CONFIG_NAND 1703 | + if (profile & ~(PROFILE_2 | PROFILE_3)) 1704 | + configure_module_pin_mux(nand_pin_mux); 1705 | +#endif 1706 | + else if (profile == PROFILE_2) { 1707 | + configure_module_pin_mux(mmc1_pin_mux); 1708 | + configure_module_pin_mux(spi0_pin_mux); 1709 | + } 1710 | + } else if (board_is_idk()) { 1711 | + /* Industrial Motor Control (IDK) */ 1712 | + configure_module_pin_mux(mii1_pin_mux); 1713 | + configure_module_pin_mux(mmc0_no_cd_pin_mux); 1714 | + } else if (board_is_evm_sk()) { 1715 | + /* Starter Kit EVM */ 1716 | + configure_module_pin_mux(i2c1_pin_mux); 1717 | + configure_module_pin_mux(gpio0_7_pin_mux); 1718 | + configure_module_pin_mux(rgmii1_pin_mux); 1719 | + configure_module_pin_mux(mmc0_pin_mux_sk_evm); 1720 | + } else if (board_is_bone_lt()) { 1721 | + /* Beaglebone LT pinmux */ 1722 | + configure_module_pin_mux(mii1_pin_mux); 1723 | + configure_module_pin_mux(mmc0_pin_mux); 1724 | +#if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT) 1725 | + configure_module_pin_mux(nand_pin_mux); 1726 | +#elif defined(CONFIG_NOR) && defined(CONFIG_EMMC_BOOT) 1727 | + configure_module_pin_mux(bone_norcape_pin_mux); 1728 | +#else 1729 | + configure_module_pin_mux(mmc1_pin_mux); 1730 | +#endif 1731 | + } else if (board_is_icev2()) { 1732 | + configure_module_pin_mux(mmc0_pin_mux); 1733 | + configure_module_pin_mux(gpio0_18_pin_mux); 1734 | + configure_module_pin_mux(uart3_icev2_pin_mux); 1735 | + configure_module_pin_mux(rmii1_pin_mux); 1736 | + configure_module_pin_mux(spi0_pin_mux); 1737 | + } else { 1738 | + /* Unknown board. We might still be able to boot. */ 1739 | + puts("Bad EEPROM or unknown board, cannot configure pinmux."); 1740 | + } 1741 | +} 1742 | diff --git a/board/ti/nova/u-boot.lds b/board/ti/nova/u-boot.lds 1743 | new file mode 100644 1744 | index 0000000..137f24a 1745 | --- /dev/null 1746 | +++ b/board/ti/nova/u-boot.lds 1747 | @@ -0,0 +1,158 @@ 1748 | +/* 1749 | + * Copyright (c) 2004-2008 Texas Instruments 1750 | + * 1751 | + * (C) Copyright 2002 1752 | + * Gary Jennejohn, DENX Software Engineering, 1753 | + * 1754 | + * See file CREDITS for list of people who contributed to this 1755 | + * project. 1756 | + * 1757 | + * This program is free software; you can redistribute it and/or 1758 | + * modify it under the terms of the GNU General Public License as 1759 | + * published by the Free Software Foundation; either version 2 of 1760 | + * the License, or (at your option) any later version. 1761 | + * 1762 | + * This program is distributed in the hope that it will be useful, 1763 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1764 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1765 | + * GNU General Public License for more details. 1766 | + * 1767 | + * You should have received a copy of the GNU General Public License 1768 | + * along with this program; if not, write to the Free Software 1769 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 1770 | + * MA 02111-1307 USA 1771 | + */ 1772 | + 1773 | +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 1774 | +OUTPUT_ARCH(arm) 1775 | +ENTRY(_start) 1776 | +SECTIONS 1777 | +{ 1778 | + . = 0x00000000; 1779 | + 1780 | + . = ALIGN(4); 1781 | + .text : 1782 | + { 1783 | + *(.__image_copy_start) 1784 | + *(.vectors) 1785 | + CPUDIR/start.o (.text*) 1786 | + board/ti/nova/built-in.o (.text*) 1787 | + *(.text*) 1788 | + } 1789 | + 1790 | + . = ALIGN(4); 1791 | + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } 1792 | + 1793 | + . = ALIGN(4); 1794 | + .data : { 1795 | + *(.data*) 1796 | + } 1797 | + 1798 | + . = ALIGN(4); 1799 | + 1800 | + . = .; 1801 | + 1802 | + . = ALIGN(4); 1803 | + .u_boot_list : { 1804 | + KEEP(*(SORT(.u_boot_list*))); 1805 | + } 1806 | + 1807 | + . = ALIGN(4); 1808 | + 1809 | + .__efi_runtime_start : { 1810 | + *(.__efi_runtime_start) 1811 | + } 1812 | + 1813 | + .efi_runtime : { 1814 | + *(efi_runtime_text) 1815 | + *(efi_runtime_data) 1816 | + } 1817 | + 1818 | + .__efi_runtime_stop : { 1819 | + *(.__efi_runtime_stop) 1820 | + } 1821 | + 1822 | + .efi_runtime_rel_start : 1823 | + { 1824 | + *(.__efi_runtime_rel_start) 1825 | + } 1826 | + 1827 | + .efi_runtime_rel : { 1828 | + *(.relefi_runtime_text) 1829 | + *(.relefi_runtime_data) 1830 | + } 1831 | + 1832 | + .efi_runtime_rel_stop : 1833 | + { 1834 | + *(.__efi_runtime_rel_stop) 1835 | + } 1836 | + 1837 | + . = ALIGN(4); 1838 | + 1839 | + .image_copy_end : 1840 | + { 1841 | + *(.__image_copy_end) 1842 | + } 1843 | + 1844 | + .rel_dyn_start : 1845 | + { 1846 | + *(.__rel_dyn_start) 1847 | + } 1848 | + 1849 | + .rel.dyn : { 1850 | + *(.rel*) 1851 | + } 1852 | + 1853 | + .rel_dyn_end : 1854 | + { 1855 | + *(.__rel_dyn_end) 1856 | + } 1857 | + 1858 | + .hash : { *(.hash*) } 1859 | + 1860 | + .end : 1861 | + { 1862 | + *(.__end) 1863 | + } 1864 | + 1865 | + _image_binary_end = .; 1866 | + 1867 | + /* 1868 | + * Deprecated: this MMU section is used by pxa at present but 1869 | + * should not be used by new boards/CPUs. 1870 | + */ 1871 | + . = ALIGN(4096); 1872 | + .mmutable : { 1873 | + *(.mmutable) 1874 | + } 1875 | + 1876 | +/* 1877 | + * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c 1878 | + * __bss_base and __bss_limit are for linker only (overlay ordering) 1879 | + */ 1880 | + 1881 | + .bss_start __rel_dyn_start (OVERLAY) : { 1882 | + KEEP(*(.__bss_start)); 1883 | + __bss_base = .; 1884 | + } 1885 | + 1886 | + .bss __bss_base (OVERLAY) : { 1887 | + *(.bss*) 1888 | + . = ALIGN(4); 1889 | + __bss_limit = .; 1890 | + } 1891 | + 1892 | + .bss_end __bss_limit (OVERLAY) : { 1893 | + KEEP(*(.__bss_end)); 1894 | + } 1895 | + 1896 | + .dynsym _image_binary_end : { *(.dynsym) } 1897 | + .dynbss : { *(.dynbss) } 1898 | + .dynstr : { *(.dynstr*) } 1899 | + .dynamic : { *(.dynamic*) } 1900 | + .gnu.hash : { *(.gnu.hash) } 1901 | + .plt : { *(.plt*) } 1902 | + .interp : { *(.interp*) } 1903 | + .gnu : { *(.gnu*) } 1904 | + .ARM.exidx : { *(.ARM.exidx*) } 1905 | +} 1906 | diff --git a/configs/nova_defconfig b/configs/nova_defconfig 1907 | new file mode 100644 1908 | index 0000000..fd7c918 1909 | --- /dev/null 1910 | +++ b/configs/nova_defconfig 1911 | @@ -0,0 +1,46 @@ 1912 | +CONFIG_ARM=y 1913 | +CONFIG_AM33XX=y 1914 | +# CONFIG_SPL_NAND_SUPPORT is not set 1915 | +CONFIG_TARGET_NOVA=y 1916 | +CONFIG_SPL_STACK_R_ADDR=0x82000000 1917 | +CONFIG_DISTRO_DEFAULTS=y 1918 | +CONFIG_FIT=y 1919 | +CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT" 1920 | +CONFIG_SYS_CONSOLE_INFO_QUIET=y 1921 | +CONFIG_VERSION_VARIABLE=y 1922 | +CONFIG_SPL=y 1923 | +CONFIG_SPL_STACK_R=y 1924 | +CONFIG_SPL_MUSB_NEW_SUPPORT=y 1925 | +CONFIG_SPL_OS_BOOT=y 1926 | +CONFIG_AUTOBOOT_KEYED=y 1927 | +CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" 1928 | +CONFIG_AUTOBOOT_DELAY_STR="d" 1929 | +CONFIG_AUTOBOOT_STOP_STR=" " 1930 | +# CONFIG_CMD_IMLS is not set 1931 | +CONFIG_CMD_ASKENV=y 1932 | +# CONFIG_CMD_FLASH is not set 1933 | +CONFIG_CMD_MMC=y 1934 | +CONFIG_CMD_SF=y 1935 | +CONFIG_CMD_SPI=y 1936 | +CONFIG_CMD_I2C=y 1937 | +CONFIG_CMD_USB=y 1938 | +CONFIG_CMD_DFU=y 1939 | +CONFIG_CMD_GPIO=y 1940 | +# CONFIG_CMD_SETEXPR is not set 1941 | +CONFIG_CMD_EXT4_WRITE=y 1942 | +CONFIG_DFU_TFTP=y 1943 | +CONFIG_DFU_MMC=y 1944 | +CONFIG_DFU_RAM=y 1945 | +CONFIG_SPI_FLASH=y 1946 | +CONFIG_SPI_FLASH_WINBOND=y 1947 | +CONFIG_SYS_NS16550=y 1948 | +CONFIG_USB=y 1949 | +CONFIG_USB_MUSB_HOST=y 1950 | +CONFIG_USB_MUSB_GADGET=y 1951 | +CONFIG_USB_STORAGE=y 1952 | +CONFIG_USB_GADGET=y 1953 | +CONFIG_USB_GADGET_DOWNLOAD=y 1954 | +CONFIG_G_DNL_MANUFACTURER="Texas Instruments" 1955 | +CONFIG_G_DNL_VENDOR_NUM=0x0451 1956 | +CONFIG_G_DNL_PRODUCT_NUM=0xd022 1957 | +CONFIG_OF_LIBFDT=y 1958 | diff --git a/include/configs/nova.h b/include/configs/nova.h 1959 | new file mode 100644 1960 | index 0000000..fb115be 1961 | --- /dev/null 1962 | +++ b/include/configs/nova.h 1963 | @@ -0,0 +1,421 @@ 1964 | +/* 1965 | + * am335x_evm.h 1966 | + * 1967 | + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 1968 | + * 1969 | + * This program is free software; you can redistribute it and/or 1970 | + * modify it under the terms of the GNU General Public License as 1971 | + * published by the Free Software Foundation version 2. 1972 | + * 1973 | + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 1974 | + * kind, whether express or implied; without even the implied warranty 1975 | + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1976 | + * GNU General Public License for more details. 1977 | + */ 1978 | + 1979 | +#ifndef __CONFIG_NOVA_H 1980 | +#define __CONFIG_NOVA_H 1981 | + 1982 | +#include 1983 | +#include 1984 | + 1985 | +#ifndef CONFIG_SPL_BUILD 1986 | +# define CONFIG_TIMESTAMP 1987 | +# define CONFIG_LZO 1988 | +#endif 1989 | + 1990 | +#define CONFIG_SYS_BOOTM_LEN (16 << 20) 1991 | + 1992 | +#define MACH_TYPE_TIAM335EVM 3589 /* Until the next sync */ 1993 | +#define CONFIG_MACH_TYPE MACH_TYPE_TIAM335EVM 1994 | +#define CONFIG_BOARD_LATE_INIT 1995 | + 1996 | +/* Clock Defines */ 1997 | +#define V_OSCK 24000000 /* Clock output from T2 */ 1998 | +#define V_SCLK (V_OSCK) 1999 | + 2000 | +/* Custom script for NOR */ 2001 | +#define CONFIG_SYS_LDSCRIPT "board/ti/nova/u-boot.lds" 2002 | + 2003 | +/* Always 128 KiB env size */ 2004 | +#define CONFIG_ENV_SIZE (128 << 10) 2005 | + 2006 | +/* Enhance our eMMC support / experience. */ 2007 | +#define CONFIG_CMD_GPT 2008 | +#define CONFIG_EFI_PARTITION 2009 | + 2010 | +#ifdef CONFIG_NAND 2011 | +#define NANDARGS \ 2012 | + "mtdids=" MTDIDS_DEFAULT "\0" \ 2013 | + "mtdparts=" MTDPARTS_DEFAULT "\0" \ 2014 | + "nandargs=setenv bootargs console=${console} " \ 2015 | + "${optargs} " \ 2016 | + "root=${nandroot} " \ 2017 | + "rootfstype=${nandrootfstype}\0" \ 2018 | + "nandroot=ubi0:rootfs rw ubi.mtd=NAND.file-system,2048\0" \ 2019 | + "nandrootfstype=ubifs rootwait=1\0" \ 2020 | + "nandboot=echo Booting from nand ...; " \ 2021 | + "run nandargs; " \ 2022 | + "nand read ${fdtaddr} NAND.u-boot-spl-os; " \ 2023 | + "nand read ${loadaddr} NAND.kernel; " \ 2024 | + "bootz ${loadaddr} - ${fdtaddr}\0" 2025 | +#else 2026 | +#define NANDARGS "" 2027 | +#endif 2028 | + 2029 | +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 2030 | + 2031 | +#undef CONFIG_SYS_PROMPT 2032 | +#define CONFIG_SYS_PROMPT "nova!> " 2033 | + 2034 | +#define BOOTENV_DEV_LEGACY_MMC(devtypeu, devtypel, instance) \ 2035 | + "bootcmd_" #devtypel #instance "=" \ 2036 | + "setenv mmcdev " #instance"; "\ 2037 | + "setenv bootpart " #instance":2 ; "\ 2038 | + "run mmcboot\0" 2039 | + 2040 | +#define BOOTENV_DEV_NAME_LEGACY_MMC(devtypeu, devtypel, instance) \ 2041 | + #devtypel #instance " " 2042 | + 2043 | +#define BOOTENV_DEV_NAND(devtypeu, devtypel, instance) \ 2044 | + "bootcmd_" #devtypel "=" \ 2045 | + "run nandboot\0" 2046 | + 2047 | +#define BOOTENV_DEV_NAME_NAND(devtypeu, devtypel, instance) \ 2048 | + #devtypel #instance " " 2049 | + 2050 | +#define BOOT_TARGET_DEVICES(func) \ 2051 | + func(MMC, mmc, 0) \ 2052 | + func(LEGACY_MMC, legacy_mmc, 0) \ 2053 | + func(MMC, mmc, 1) \ 2054 | + func(LEGACY_MMC, legacy_mmc, 1) \ 2055 | + func(NAND, nand, 0) \ 2056 | + func(PXE, pxe, na) \ 2057 | + func(DHCP, dhcp, na) 2058 | + 2059 | +#define CONFIG_BOOTCOMMAND \ 2060 | + "if test ${boot_fit} -eq 1; then " \ 2061 | + "run update_to_fit;" \ 2062 | + "fi;" \ 2063 | + "run findfdt; " \ 2064 | + "run init_console; " \ 2065 | + "run envboot; " \ 2066 | + "run distro_bootcmd" 2067 | + 2068 | +#include 2069 | + 2070 | +#ifndef CONFIG_SPL_BUILD 2071 | +#define CONFIG_EXTRA_ENV_SETTINGS \ 2072 | + DEFAULT_LINUX_BOOT_ENV \ 2073 | + DEFAULT_MMC_TI_ARGS \ 2074 | + DEFAULT_FIT_TI_ARGS \ 2075 | + "bootpart=0:2\0" \ 2076 | + "bootdir=/boot\0" \ 2077 | + "bootfile=zImage\0" \ 2078 | + "fdtfile=undefined\0" \ 2079 | + "console=ttyO0,115200n8\0" \ 2080 | + "partitions=" \ 2081 | + "uuid_disk=${uuid_gpt_disk};" \ 2082 | + "name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \ 2083 | + "optargs=\0" \ 2084 | + "ramroot=/dev/ram0 rw\0" \ 2085 | + "ramrootfstype=ext2\0" \ 2086 | + "spiroot=/dev/mtdblock4 rw\0" \ 2087 | + "spirootfstype=jffs2\0" \ 2088 | + "spisrcaddr=0xe0000\0" \ 2089 | + "spiimgsize=0x362000\0" \ 2090 | + "spibusno=0\0" \ 2091 | + "spiargs=setenv bootargs console=${console} " \ 2092 | + "${optargs} " \ 2093 | + "root=${spiroot} " \ 2094 | + "rootfstype=${spirootfstype}\0" \ 2095 | + "ramargs=setenv bootargs console=${console} " \ 2096 | + "${optargs} " \ 2097 | + "root=${ramroot} " \ 2098 | + "rootfstype=${ramrootfstype}\0" \ 2099 | + "loadramdisk=load mmc ${mmcdev} ${rdaddr} ramdisk.gz\0" \ 2100 | + "spiboot=echo Booting from spi ...; " \ 2101 | + "run spiargs; " \ 2102 | + "sf probe ${spibusno}:0; " \ 2103 | + "sf read ${loadaddr} ${spisrcaddr} ${spiimgsize}; " \ 2104 | + "bootz ${loadaddr}\0" \ 2105 | + "ramboot=echo Booting from ramdisk ...; " \ 2106 | + "run ramargs; " \ 2107 | + "bootz ${loadaddr} ${rdaddr} ${fdtaddr}\0" \ 2108 | + "findfdt="\ 2109 | + "if test $board_name = A335BONE; then " \ 2110 | + "setenv fdtfile am335x-bone.dtb; fi; " \ 2111 | + "if test $board_name = A335BNLT; then " \ 2112 | + "setenv fdtfile am335x-boneblack.dtb; fi; " \ 2113 | + "if test $board_name = BBG1; then " \ 2114 | + "setenv fdtfile am335x-bonegreen.dtb; fi; " \ 2115 | + "if test $board_name = A33515BB; then " \ 2116 | + "setenv fdtfile am335x-evm.dtb; fi; " \ 2117 | + "if test $board_name = A335X_SK; then " \ 2118 | + "setenv fdtfile am335x-evmsk.dtb; fi; " \ 2119 | + "if test $board_name = A335_ICE; then " \ 2120 | + "setenv fdtfile am335x-icev2.dtb; fi; " \ 2121 | + "if test $fdtfile = undefined; then " \ 2122 | + "echo WARNING: Could not determine device tree to use; fi; \0" \ 2123 | + "init_console=" \ 2124 | + "if test $board_name = A335_ICE; then "\ 2125 | + "setenv console ttyO3,115200n8;" \ 2126 | + "else " \ 2127 | + "setenv console ttyO0,115200n8;" \ 2128 | + "fi;\0" \ 2129 | + NANDARGS \ 2130 | + NETARGS \ 2131 | + DFUARGS \ 2132 | + BOOTENV 2133 | +#endif 2134 | + 2135 | +/* NS16550 Configuration */ 2136 | +#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* Base EVM has UART0 */ 2137 | +#define CONFIG_SYS_NS16550_COM2 0x48022000 /* UART1 */ 2138 | +#define CONFIG_SYS_NS16550_COM3 0x48024000 /* UART2 */ 2139 | +#define CONFIG_SYS_NS16550_COM4 0x481a6000 /* UART3 */ 2140 | +#define CONFIG_SYS_NS16550_COM5 0x481a8000 /* UART4 */ 2141 | +#define CONFIG_SYS_NS16550_COM6 0x481aa000 /* UART5 */ 2142 | +#define CONFIG_BAUDRATE 115200 2143 | + 2144 | +#define CONFIG_CMD_EEPROM 2145 | +#define CONFIG_ENV_EEPROM_IS_ON_I2C 2146 | +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */ 2147 | +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 2148 | + 2149 | +/* PMIC support */ 2150 | +#define CONFIG_POWER_TPS65217 2151 | +#define CONFIG_POWER_TPS65910 2152 | + 2153 | +/* SPL */ 2154 | +#ifndef CONFIG_NOR_BOOT 2155 | +/* Bootcount using the RTC block */ 2156 | +#define CONFIG_BOOTCOUNT_LIMIT 2157 | +#define CONFIG_BOOTCOUNT_AM33XX 2158 | +#define CONFIG_SYS_BOOTCOUNT_BE 2159 | + 2160 | +/* USB gadget RNDIS */ 2161 | + 2162 | +#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-omap2/am33xx/u-boot-spl.lds" 2163 | +#endif 2164 | + 2165 | +#ifdef CONFIG_NAND 2166 | +/* NAND: device related configs */ 2167 | +#define CONFIG_SYS_NAND_5_ADDR_CYCLE 2168 | +#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ 2169 | + CONFIG_SYS_NAND_PAGE_SIZE) 2170 | +#define CONFIG_SYS_NAND_PAGE_SIZE 2048 2171 | +#define CONFIG_SYS_NAND_OOBSIZE 64 2172 | +#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) 2173 | +/* NAND: driver related configs */ 2174 | +#define CONFIG_NAND_OMAP_GPMC 2175 | +#define CONFIG_NAND_OMAP_GPMC_PREFETCH 2176 | +#define CONFIG_NAND_OMAP_ELM 2177 | +#define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS 2178 | +#define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ 2179 | + 10, 11, 12, 13, 14, 15, 16, 17, \ 2180 | + 18, 19, 20, 21, 22, 23, 24, 25, \ 2181 | + 26, 27, 28, 29, 30, 31, 32, 33, \ 2182 | + 34, 35, 36, 37, 38, 39, 40, 41, \ 2183 | + 42, 43, 44, 45, 46, 47, 48, 49, \ 2184 | + 50, 51, 52, 53, 54, 55, 56, 57, } 2185 | + 2186 | +#define CONFIG_SYS_NAND_ECCSIZE 512 2187 | +#define CONFIG_SYS_NAND_ECCBYTES 14 2188 | +#define CONFIG_SYS_NAND_ONFI_DETECTION 2189 | +#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW 2190 | +#define MTDIDS_DEFAULT "nand0=nand.0" 2191 | +#define MTDPARTS_DEFAULT "mtdparts=nand.0:" \ 2192 | + "128k(NAND.SPL)," \ 2193 | + "128k(NAND.SPL.backup1)," \ 2194 | + "128k(NAND.SPL.backup2)," \ 2195 | + "128k(NAND.SPL.backup3)," \ 2196 | + "256k(NAND.u-boot-spl-os)," \ 2197 | + "1m(NAND.u-boot)," \ 2198 | + "128k(NAND.u-boot-env)," \ 2199 | + "128k(NAND.u-boot-env.backup1)," \ 2200 | + "8m(NAND.kernel)," \ 2201 | + "-(NAND.file-system)" 2202 | +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x000c0000 2203 | +/* NAND: SPL related configs */ 2204 | +#ifdef CONFIG_SPL_NAND_SUPPORT 2205 | +#define CONFIG_SPL_NAND_AM33XX_BCH 2206 | +#endif 2207 | +#ifdef CONFIG_SPL_OS_BOOT 2208 | +#define CONFIG_CMD_SPL_NAND_OFS 0x00080000 /* os parameters */ 2209 | +#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000 /* kernel offset */ 2210 | +#define CONFIG_CMD_SPL_WRITE_SIZE 0x2000 2211 | +#endif 2212 | +#endif /* !CONFIG_NAND */ 2213 | + 2214 | +/* 2215 | + * For NOR boot, we must set this to the start of where NOR is mapped 2216 | + * in memory. 2217 | + */ 2218 | +#ifdef CONFIG_NOR_BOOT 2219 | +#define CONFIG_SYS_TEXT_BASE 0x08000000 2220 | +#endif 2221 | + 2222 | +/* 2223 | + * USB configuration. We enable MUSB support, both for host and for 2224 | + * gadget. We set USB0 as peripheral and USB1 as host, based on the 2225 | + * board schematic and physical port wired to each. Then for host we 2226 | + * add mass storage support and for gadget we add both RNDIS ethernet 2227 | + * and DFU. 2228 | + */ 2229 | +#define CONFIG_USB_MUSB_DSPS 2230 | +#define CONFIG_ARCH_MISC_INIT 2231 | +#define CONFIG_USB_MUSB_PIO_ONLY 2232 | +#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT 2233 | +#define CONFIG_AM335X_USB0 2234 | +#define CONFIG_AM335X_USB0_MODE MUSB_PERIPHERAL 2235 | +#define CONFIG_AM335X_USB1 2236 | +#define CONFIG_AM335X_USB1_MODE MUSB_HOST 2237 | + 2238 | +#ifndef CONFIG_SPL_USBETH_SUPPORT 2239 | +/* Fastboot */ 2240 | +#define CONFIG_USB_FUNCTION_FASTBOOT 2241 | +#define CONFIG_CMD_FASTBOOT 2242 | +#define CONFIG_ANDROID_BOOT_IMAGE 2243 | +#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR 2244 | +#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000 2245 | + 2246 | +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 1 2247 | +#endif 2248 | + 2249 | +#ifdef CONFIG_USB_MUSB_GADGET 2250 | +/* Removing USB gadget and can be enabled adter adding support usb DM */ 2251 | +#ifndef CONFIG_DM_ETH 2252 | +#define CONFIG_USB_ETHER 2253 | +#define CONFIG_USB_ETH_RNDIS 2254 | +#define CONFIG_USBNET_HOST_ADDR "de:ad:be:af:00:00" 2255 | +#endif /* CONFIG_DM_ETH */ 2256 | +#endif /* CONFIG_USB_MUSB_GADGET */ 2257 | + 2258 | +/* 2259 | + * Disable MMC DM for SPL build and can be re-enabled after adding 2260 | + * DM support in SPL 2261 | + */ 2262 | +#ifdef CONFIG_SPL_BUILD 2263 | +#undef CONFIG_DM_MMC 2264 | +#undef CONFIG_TIMER 2265 | +#undef CONFIG_DM_USB 2266 | +#endif 2267 | + 2268 | +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_USBETH_SUPPORT) 2269 | +/* Remove other SPL modes. */ 2270 | +#define CONFIG_ENV_IS_NOWHERE 2271 | +#undef CONFIG_ENV_IS_IN_NAND 2272 | +/* disable host part of MUSB in SPL */ 2273 | +/* disable EFI partitions and partition UUID support */ 2274 | +#undef CONFIG_PARTITION_UUIDS 2275 | +#undef CONFIG_EFI_PARTITION 2276 | +#endif 2277 | + 2278 | +/* USB Device Firmware Update support */ 2279 | +#ifndef CONFIG_SPL_BUILD 2280 | +#define DFUARGS \ 2281 | + "dfu_alt_info_emmc=rawemmc raw 0 3751936\0" \ 2282 | + DFU_ALT_INFO_MMC \ 2283 | + DFU_ALT_INFO_RAM \ 2284 | + DFU_ALT_INFO_NAND 2285 | +#endif 2286 | + 2287 | +/* 2288 | + * Default to using SPI for environment, etc. 2289 | + * 0x000000 - 0x020000 : SPL (128KiB) 2290 | + * 0x020000 - 0x0A0000 : U-Boot (512KiB) 2291 | + * 0x0A0000 - 0x0BFFFF : First copy of U-Boot Environment (128KiB) 2292 | + * 0x0C0000 - 0x0DFFFF : Second copy of U-Boot Environment (128KiB) 2293 | + * 0x0E0000 - 0x442000 : Linux Kernel 2294 | + * 0x442000 - 0x800000 : Userland 2295 | + */ 2296 | +#if defined(CONFIG_SPI_BOOT) 2297 | +/* SPL related */ 2298 | +#define CONFIG_SPL_SPI_LOAD 2299 | +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000 2300 | + 2301 | +#define CONFIG_ENV_IS_IN_SPI_FLASH 2302 | +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT 2303 | +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED 2304 | +#define CONFIG_ENV_SECT_SIZE (4 << 10) /* 4 KB sectors */ 2305 | +#define CONFIG_ENV_OFFSET (768 << 10) /* 768 KiB in */ 2306 | +#define CONFIG_ENV_OFFSET_REDUND (896 << 10) /* 896 KiB in */ 2307 | +#define MTDIDS_DEFAULT "nor0=m25p80-flash.0" 2308 | +#define MTDPARTS_DEFAULT "mtdparts=m25p80-flash.0:128k(SPL)," \ 2309 | + "512k(u-boot),128k(u-boot-env1)," \ 2310 | + "128k(u-boot-env2),3464k(kernel)," \ 2311 | + "-(rootfs)" 2312 | +#elif defined(CONFIG_EMMC_BOOT) 2313 | +#define CONFIG_ENV_IS_IN_MMC 2314 | +#define CONFIG_SYS_MMC_ENV_DEV 1 2315 | +#define CONFIG_SYS_MMC_ENV_PART 2 2316 | +#define CONFIG_ENV_OFFSET 0x0 2317 | +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) 2318 | +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT 2319 | +#elif defined(CONFIG_NOR_BOOT) 2320 | +#define CONFIG_ENV_IS_IN_FLASH 2321 | +#define CONFIG_ENV_SECT_SIZE (128 << 10) /* 128 KiB */ 2322 | +#define CONFIG_ENV_OFFSET (512 << 10) /* 512 KiB */ 2323 | +#define CONFIG_ENV_OFFSET_REDUND (768 << 10) /* 768 KiB */ 2324 | +#define MTDIDS_DEFAULT "nor0=physmap-flash.0" 2325 | +#define MTDPARTS_DEFAULT "mtdparts=physmap-flash.0:" \ 2326 | + "512k(u-boot)," \ 2327 | + "128k(u-boot-env1)," \ 2328 | + "128k(u-boot-env2)," \ 2329 | + "4m(kernel),-(rootfs)" 2330 | +#elif defined(CONFIG_ENV_IS_IN_NAND) 2331 | +#define CONFIG_ENV_OFFSET 0x001c0000 2332 | +#define CONFIG_ENV_OFFSET_REDUND 0x001e0000 2333 | +#define CONFIG_SYS_ENV_SECT_SIZE CONFIG_SYS_NAND_BLOCK_SIZE 2334 | +#elif !defined(CONFIG_ENV_IS_NOWHERE) 2335 | +/* Not NAND, SPI, NOR or eMMC env, so put ENV in a file on FAT */ 2336 | +#define CONFIG_ENV_IS_IN_FAT 2337 | +#define FAT_ENV_INTERFACE "mmc" 2338 | +#define FAT_ENV_DEVICE_AND_PART "0:1" 2339 | +#define FAT_ENV_FILE "uboot.env" 2340 | +#endif 2341 | + 2342 | +/* SPI flash. */ 2343 | +#define CONFIG_SF_DEFAULT_SPEED 24000000 2344 | + 2345 | +/* Network. */ 2346 | +#define CONFIG_PHY_GIGE 2347 | +#define CONFIG_PHYLIB 2348 | +#define CONFIG_PHY_SMSC 2349 | +/* Enable Atheros phy driver */ 2350 | +#define CONFIG_PHY_ATHEROS 2351 | + 2352 | +/* 2353 | + * NOR Size = 16 MiB 2354 | + * Number of Sectors/Blocks = 128 2355 | + * Sector Size = 128 KiB 2356 | + * Word length = 16 bits 2357 | + * Default layout: 2358 | + * 0x000000 - 0x07FFFF : U-Boot (512 KiB) 2359 | + * 0x080000 - 0x09FFFF : First copy of U-Boot Environment (128 KiB) 2360 | + * 0x0A0000 - 0x0BFFFF : Second copy of U-Boot Environment (128 KiB) 2361 | + * 0x0C0000 - 0x4BFFFF : Linux Kernel (4 MiB) 2362 | + * 0x4C0000 - 0xFFFFFF : Userland (11 MiB + 256 KiB) 2363 | + */ 2364 | +#if defined(CONFIG_NOR) 2365 | +#undef CONFIG_SYS_NO_FLASH 2366 | +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 2367 | +#define CONFIG_SYS_FLASH_PROTECTION 2368 | +#define CONFIG_SYS_FLASH_CFI 2369 | +#define CONFIG_FLASH_CFI_DRIVER 2370 | +#define CONFIG_FLASH_CFI_MTD 2371 | +#define CONFIG_SYS_MAX_FLASH_SECT 128 2372 | +#define CONFIG_SYS_MAX_FLASH_BANKS 1 2373 | +#define CONFIG_SYS_FLASH_BASE (0x08000000) 2374 | +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT 2375 | +#define CONFIG_SYS_FLASH_SIZE 0x01000000 2376 | +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE 2377 | +#endif /* NOR support */ 2378 | + 2379 | +#ifdef CONFIG_DRIVER_TI_CPSW 2380 | +#define CONFIG_CLOCK_SYNTHESIZER 2381 | +#define CLK_SYNTHESIZER_I2C_ADDR 0x65 2382 | +#endif 2383 | + 2384 | +#endif /* ! __CONFIG_NOVA_H */ 2385 | -- 2386 | 2.1.4 2387 | 2388 | -------------------------------------------------------------------------------- /Chapter04/build-linux-bbb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATH=${HOME}/x-tools/arm-cortex_a8-linux-gnueabihf/bin/:$PATH 4 | 5 | cd linux-stable 6 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 7 | 8 | make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- mrproper 9 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 10 | 11 | make ARCH=arm multi_v7_defconfig 12 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 13 | 14 | make -j4 ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- zImage 15 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 16 | 17 | make -j4 ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- modules 18 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 19 | 20 | make ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- dtbs 21 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/build-linux-versatilepb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATH=${HOME}/x-tools/arm-unknown-linux-gnueabi/bin/:$PATH 4 | 5 | cd linux-stable 6 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 7 | 8 | make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- mrproper 9 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 10 | 11 | make versatile_defconfig 12 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 13 | 14 | make -j4 ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- zImage 15 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 16 | 17 | make -j4 ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- modules 18 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 19 | 20 | make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- dtbs 21 | if [ $? != 0 ]; then echo "ERROR"; exit; fi 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/nova.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | /dts-v1/; 9 | 10 | #include "am33xx.dtsi" 11 | #include "am335x-bone-common.dtsi" 12 | #include 13 | 14 | / { 15 | model = "Nova"; 16 | compatible = "ti,nova", "ti,am33xx"; 17 | }; 18 | 19 | &ldo3_reg { 20 | regulator-min-microvolt = <1800000>; 21 | regulator-max-microvolt = <1800000>; 22 | regulator-always-on; 23 | }; 24 | 25 | &mmc1 { 26 | vmmc-supply = <&vmmcsd_fixed>; 27 | }; 28 | 29 | &mmc2 { 30 | vmmc-supply = <&vmmcsd_fixed>; 31 | pinctrl-names = "default"; 32 | pinctrl-0 = <&emmc_pins>; 33 | bus-width = <8>; 34 | status = "okay"; 35 | }; 36 | 37 | &am33xx_pinmux { 38 | nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { 39 | pinctrl-single,pins = < 40 | AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ 41 | AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ 42 | AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ 43 | AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ 44 | AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ 45 | AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ 46 | AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ 47 | AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ 48 | AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ 49 | AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ 50 | AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ 51 | AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ 52 | AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ 53 | AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ 54 | AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ 55 | AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ 56 | AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ 57 | AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ 58 | AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ 59 | AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ 60 | AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ 61 | >; 62 | }; 63 | nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { 64 | pinctrl-single,pins = < 65 | AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ 66 | >; 67 | }; 68 | 69 | mcasp0_pins: mcasp0_pins { 70 | pinctrl-single,pins = < 71 | AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ 72 | AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ 73 | AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ 74 | AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ 75 | AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ 76 | >; 77 | }; 78 | }; 79 | 80 | &lcdc { 81 | status = "okay"; 82 | port { 83 | lcdc_0: endpoint@0 { 84 | remote-endpoint = <&hdmi_0>; 85 | }; 86 | }; 87 | }; 88 | 89 | &i2c0 { 90 | tda19988: tda19988 { 91 | compatible = "nxp,tda998x"; 92 | reg = <0x70>; 93 | 94 | pinctrl-names = "default", "off"; 95 | pinctrl-0 = <&nxp_hdmi_bonelt_pins>; 96 | pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; 97 | 98 | #sound-dai-cells = <0>; 99 | audio-ports = < TDA998x_I2S 0x03>; 100 | 101 | ports { 102 | port@0 { 103 | hdmi_0: endpoint@0 { 104 | remote-endpoint = <&lcdc_0>; 105 | }; 106 | }; 107 | }; 108 | }; 109 | }; 110 | 111 | &rtc { 112 | system-power-controller; 113 | }; 114 | 115 | &mcasp0 { 116 | #sound-dai-cells = <0>; 117 | pinctrl-names = "default"; 118 | pinctrl-0 = <&mcasp0_pins>; 119 | status = "okay"; 120 | op-mode = <0>; /* MCASP_IIS_MODE */ 121 | tdm-slots = <2>; 122 | serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ 123 | 0 0 1 0 124 | >; 125 | tx-num-evt = <32>; 126 | rx-num-evt = <32>; 127 | }; 128 | 129 | / { 130 | clk_mcasp0_fixed: clk_mcasp0_fixed { 131 | #clock-cells = <0>; 132 | compatible = "fixed-clock"; 133 | clock-frequency = <24576000>; 134 | }; 135 | 136 | clk_mcasp0: clk_mcasp0 { 137 | #clock-cells = <0>; 138 | compatible = "gpio-gate-clock"; 139 | clocks = <&clk_mcasp0_fixed>; 140 | enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ 141 | }; 142 | 143 | sound { 144 | compatible = "simple-audio-card"; 145 | simple-audio-card,name = "TI BeagleBone Black"; 146 | simple-audio-card,format = "i2s"; 147 | simple-audio-card,bitclock-master = <&dailink0_master>; 148 | simple-audio-card,frame-master = <&dailink0_master>; 149 | 150 | dailink0_master: simple-audio-card,cpu { 151 | sound-dai = <&mcasp0>; 152 | clocks = <&clk_mcasp0>; 153 | }; 154 | 155 | simple-audio-card,codec { 156 | sound-dai = <&tda19988>; 157 | }; 158 | }; 159 | }; 160 | -------------------------------------------------------------------------------- /Chapter05/run-qemu-initramfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | KERNEL=zImage 4 | DTB=versatile-pb.dtb 5 | INITRAMFS=initramfs.cpio.gz 6 | 7 | if [ ! -f ${KERNEL} ]; then 8 | echo "${KERNEL} does not exist" 9 | exit 1 10 | fi 11 | if [ ! -f ${DTB} ]; then 12 | echo "${DTB} does not exist" 13 | exit 1 14 | fi 15 | 16 | QEMU_AUDIO_DRV=none \ 17 | qemu-system-arm -m 256M -nographic -M versatilepb -kernel ${KERNEL} -append "console=ttyAMA0,115200 rdinit=/bin/sh" -dtb ${DTB} -initrd ${INITRAMFS} 18 | 19 | -------------------------------------------------------------------------------- /Chapter05/run-qemu-nfsroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | KERNEL=zImage 4 | DTB=versatile-pb.dtb 5 | ROOTDIR=${HOME}/rootfs 6 | HOST_IP=192.168.1.1 7 | TARGET_IP=192.168.1.101 8 | NET_NUMBER=192.168.1.0 9 | NET_MASK=255.255.255.0 10 | 11 | if [ ! -f ${KERNEL} ]; then 12 | echo "${KERNEL} does not exist" 13 | exit 1 14 | fi 15 | if [ ! -f ${DTB} ]; then 16 | echo "${DTB} does not exist" 17 | exit 1 18 | fi 19 | 20 | sudo tunctl -u $(whoami) -t tap0 21 | sudo ifconfig tap0 ${HOST_IP} 22 | sudo route add -net ${NET_NUMBER} netmask ${NET_MASK} dev tap0 23 | sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" 24 | 25 | QEMU_AUDIO_DRV=none \ 26 | qemu-system-arm -m 256M -nographic -M versatilepb -kernel ${KERNEL} -append "console=ttyAMA0,115200 root=/dev/nfs rw nfsroot=${HOST_IP}:${ROOTDIR} ip=${TARGET_IP}" -dtb ${DTB} -net nic -net tap,ifname=tap0,script=no 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter06/buildroot/board/melp/nova/genimage.cfg: -------------------------------------------------------------------------------- 1 | image boot.vfat { 2 | vfat { 3 | files = { 4 | "MLO", 5 | "u-boot.img", 6 | "zImage", 7 | "uEnv.txt", 8 | "nova.dtb", 9 | } 10 | } 11 | size = 16M 12 | } 13 | 14 | image sdcard.img { 15 | hdimage { 16 | } 17 | 18 | partition u-boot { 19 | partition-type = 0xC 20 | bootable = "true" 21 | image = "boot.vfat" 22 | } 23 | 24 | partition rootfs { 25 | partition-type = 0x83 26 | image = "rootfs.ext4" 27 | size = 512M 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter06/buildroot/board/melp/nova/nova.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | /dts-v1/; 9 | 10 | #include "am33xx.dtsi" 11 | #include "am335x-bone-common.dtsi" 12 | #include 13 | 14 | / { 15 | model = "Nova"; 16 | compatible = "ti,nova", "ti,am33xx"; 17 | }; 18 | 19 | &ldo3_reg { 20 | regulator-min-microvolt = <1800000>; 21 | regulator-max-microvolt = <1800000>; 22 | regulator-always-on; 23 | }; 24 | 25 | &mmc1 { 26 | vmmc-supply = <&vmmcsd_fixed>; 27 | }; 28 | 29 | &mmc2 { 30 | vmmc-supply = <&vmmcsd_fixed>; 31 | pinctrl-names = "default"; 32 | pinctrl-0 = <&emmc_pins>; 33 | bus-width = <8>; 34 | status = "okay"; 35 | }; 36 | 37 | &am33xx_pinmux { 38 | nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { 39 | pinctrl-single,pins = < 40 | AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ 41 | AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ 42 | AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ 43 | AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ 44 | AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ 45 | AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ 46 | AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ 47 | AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ 48 | AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ 49 | AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ 50 | AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ 51 | AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ 52 | AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ 53 | AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ 54 | AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ 55 | AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ 56 | AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ 57 | AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ 58 | AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ 59 | AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ 60 | AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ 61 | >; 62 | }; 63 | nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { 64 | pinctrl-single,pins = < 65 | AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ 66 | >; 67 | }; 68 | 69 | mcasp0_pins: mcasp0_pins { 70 | pinctrl-single,pins = < 71 | AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ 72 | AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ 73 | AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ 74 | AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ 75 | AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ 76 | >; 77 | }; 78 | }; 79 | 80 | &lcdc { 81 | status = "okay"; 82 | port { 83 | lcdc_0: endpoint@0 { 84 | remote-endpoint = <&hdmi_0>; 85 | }; 86 | }; 87 | }; 88 | 89 | &i2c0 { 90 | tda19988: tda19988 { 91 | compatible = "nxp,tda998x"; 92 | reg = <0x70>; 93 | 94 | pinctrl-names = "default", "off"; 95 | pinctrl-0 = <&nxp_hdmi_bonelt_pins>; 96 | pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; 97 | 98 | #sound-dai-cells = <0>; 99 | audio-ports = < TDA998x_I2S 0x03>; 100 | 101 | ports { 102 | port@0 { 103 | hdmi_0: endpoint@0 { 104 | remote-endpoint = <&lcdc_0>; 105 | }; 106 | }; 107 | }; 108 | }; 109 | }; 110 | 111 | &rtc { 112 | system-power-controller; 113 | }; 114 | 115 | &mcasp0 { 116 | #sound-dai-cells = <0>; 117 | pinctrl-names = "default"; 118 | pinctrl-0 = <&mcasp0_pins>; 119 | status = "okay"; 120 | op-mode = <0>; /* MCASP_IIS_MODE */ 121 | tdm-slots = <2>; 122 | serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ 123 | 0 0 1 0 124 | >; 125 | tx-num-evt = <32>; 126 | rx-num-evt = <32>; 127 | }; 128 | 129 | / { 130 | clk_mcasp0_fixed: clk_mcasp0_fixed { 131 | #clock-cells = <0>; 132 | compatible = "fixed-clock"; 133 | clock-frequency = <24576000>; 134 | }; 135 | 136 | clk_mcasp0: clk_mcasp0 { 137 | #clock-cells = <0>; 138 | compatible = "gpio-gate-clock"; 139 | clocks = <&clk_mcasp0_fixed>; 140 | enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ 141 | }; 142 | 143 | sound { 144 | compatible = "simple-audio-card"; 145 | simple-audio-card,name = "TI BeagleBone Black"; 146 | simple-audio-card,format = "i2s"; 147 | simple-audio-card,bitclock-master = <&dailink0_master>; 148 | simple-audio-card,frame-master = <&dailink0_master>; 149 | 150 | dailink0_master: simple-audio-card,cpu { 151 | sound-dai = <&mcasp0>; 152 | clocks = <&clk_mcasp0>; 153 | }; 154 | 155 | simple-audio-card,codec { 156 | sound-dai = <&tda19988>; 157 | }; 158 | }; 159 | }; 160 | -------------------------------------------------------------------------------- /Chapter06/buildroot/board/melp/nova/post-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # post-image.sh for CircuitCo BeagleBone and TI am335x-evm 3 | # 2014, Marcin Jabrzyk 4 | # 2016, Lothar Felten 5 | 6 | BOARD_DIR="$(dirname $0)" 7 | 8 | cp ${BOARD_DIR}/uEnv.txt $BINARIES_DIR/uEnv.txt 9 | 10 | GENIMAGE_CFG="${BOARD_DIR}/genimage.cfg" 11 | GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp" 12 | 13 | rm -rf "${GENIMAGE_TMP}" 14 | 15 | genimage \ 16 | --rootpath "${TARGET_DIR}" \ 17 | --tmppath "${GENIMAGE_TMP}" \ 18 | --inputpath "${BINARIES_DIR}" \ 19 | --outputpath "${BINARIES_DIR}" \ 20 | --config "${GENIMAGE_CFG}" 21 | -------------------------------------------------------------------------------- /Chapter06/buildroot/board/melp/nova/uEnv.txt: -------------------------------------------------------------------------------- 1 | bootpart=0:1 2 | bootdir= 3 | bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait 4 | uenvcmd=fatload mmc 0:1 88000000 nova.dtb;fatload mmc 0:1 82000000 zImage;bootz 82000000 - 88000000 5 | 6 | -------------------------------------------------------------------------------- /Chapter06/buildroot/configs/nova_defconfig: -------------------------------------------------------------------------------- 1 | BR2_arm=y 2 | BR2_cortex_a8=y 3 | BR2_GLOBAL_PATCH_DIR="board/beaglebone/patches" 4 | BR2_TARGET_GENERIC_GETTY_PORT="ttyO0" 5 | BR2_ROOTFS_POST_IMAGE_SCRIPT="board/melp/nova/post-image.sh" 6 | BR2_LINUX_KERNEL=y 7 | BR2_LINUX_KERNEL_DEFCONFIG="omap2plus" 8 | BR2_LINUX_KERNEL_DTS_SUPPORT=y 9 | BR2_LINUX_KERNEL_USE_CUSTOM_DTS=y 10 | BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="board/melp/nova/nova.dts" 11 | BR2_PACKAGE_HELLOWORLD=y 12 | BR2_TARGET_ROOTFS_EXT2=y 13 | BR2_TARGET_ROOTFS_EXT2_4=y 14 | BR2_TARGET_UBOOT=y 15 | BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y 16 | BR2_TARGET_UBOOT_CUSTOM_VERSION=y 17 | BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2017.01" 18 | BR2_TARGET_UBOOT_PATCH="board/melp/nova/0001-BSP-for-Nova.patch" 19 | BR2_TARGET_UBOOT_BOARD_DEFCONFIG="am335x_evm" 20 | BR2_TARGET_UBOOT_NEEDS_DTC=y 21 | # BR2_TARGET_UBOOT_FORMAT_BIN is not set 22 | BR2_TARGET_UBOOT_FORMAT_IMG=y 23 | BR2_TARGET_UBOOT_FORMAT_CUSTOM=y 24 | BR2_TARGET_UBOOT_FORMAT_CUSTOM_NAME="spl/u-boot-spl.bin" 25 | BR2_TARGET_UBOOT_SPL=y 26 | BR2_TARGET_UBOOT_SPL_NAME="MLO" 27 | BR2_PACKAGE_HOST_DOSFSTOOLS=y 28 | BR2_PACKAGE_HOST_GENIMAGE=y 29 | BR2_PACKAGE_HOST_MTOOLS=y 30 | -------------------------------------------------------------------------------- /Chapter06/buildroot/package/helloworld/Config.in: -------------------------------------------------------------------------------- 1 | config BR2_PACKAGE_HELLOWORLD 2 | bool "helloworld" 3 | help 4 | A friendly program that prints Hello World! every 10s 5 | -------------------------------------------------------------------------------- /Chapter06/buildroot/package/helloworld/helloworld.mk: -------------------------------------------------------------------------------- 1 | HELLOWORLD_VERSION = 1.0.0 2 | HELLOWORLD_SITE = /home/chris/MELP/helloworld 3 | HELLOWORLD_SITE_METHOD = local 4 | 5 | define HELLOWORLD_BUILD_CMDS 6 | $(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D) all 7 | endef 8 | 9 | define HELLOWORLD_INSTALL_TARGET_CMDS 10 | $(INSTALL) -D -m 0755 $(@D)/helloworld $(TARGET_DIR)/usr/bin/helloworld 11 | endef 12 | 13 | $(eval $(generic-package)) 14 | -------------------------------------------------------------------------------- /Chapter06/helloworld/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-Wall -g 2 | PROGS=helloworld 3 | 4 | all: $(PROGS) 5 | 6 | $(PROGS): $(PROGS).c 7 | $(CC) $(CFLAGS) -o $@ $^ 8 | 9 | clean: 10 | rm -f *.o 11 | rm -f $(PROGS) 12 | 13 | install: 14 | cp $(PROGS) $(TARGET_DIR)/usr/local/bin 15 | -------------------------------------------------------------------------------- /Chapter06/helloworld/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main (int argc, char *argv[]) 5 | { 6 | printf("Hello world!\n"); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/COPYING.MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/README: -------------------------------------------------------------------------------- 1 | This README file contains information on the contents of the 2 | nova layer. 3 | 4 | Please see the corresponding sections below for details. 5 | 6 | 7 | Dependencies 8 | ============ 9 | 10 | This layer depends on: 11 | 12 | URI: git://git.openembedded.org/bitbake 13 | branch: master 14 | 15 | URI: git://git.openembedded.org/openembedded-core 16 | layers: meta 17 | branch: master 18 | 19 | URI: git://git.yoctoproject.org/xxxx 20 | layers: xxxx 21 | branch: master 22 | 23 | 24 | Patches 25 | ======= 26 | 27 | Please submit any patches against the nova layer to the 28 | xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer: 29 | 30 | Maintainer: XXX YYYYYY 31 | 32 | 33 | Table of Contents 34 | ================= 35 | 36 | I. Adding the nova layer to your build 37 | II. Misc 38 | 39 | 40 | I. Adding the nova layer to your build 41 | ================================================= 42 | 43 | --- replace with specific instructions for the nova layer --- 44 | 45 | In order to use this layer, you need to make the build system aware of 46 | it. 47 | 48 | Assuming the nova layer exists at the top-level of your 49 | yocto build tree, you can add it to the build system by adding the 50 | location of the nova layer to bblayers.conf, along with any 51 | other layers needed. e.g.: 52 | 53 | BBLAYERS ?= " \ 54 | /path/to/yocto/meta \ 55 | /path/to/yocto/meta-poky \ 56 | /path/to/yocto/meta-yocto-bsp \ 57 | /path/to/yocto/meta-nova \ 58 | " 59 | 60 | 61 | II. Misc 62 | ======== 63 | 64 | --- replace with specific information about the nova layer --- 65 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/conf/layer.conf: -------------------------------------------------------------------------------- 1 | # We have a conf and classes directory, add to BBPATH 2 | BBPATH .= ":${LAYERDIR}" 3 | 4 | # We have recipes-* directories, add to BBFILES 5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ 6 | ${LAYERDIR}/recipes-*/*/*.bbappend" 7 | 8 | BBFILE_COLLECTIONS += "nova" 9 | BBFILE_PATTERN_nova = "^${LAYERDIR}/" 10 | BBFILE_PRIORITY_nova = "6" 11 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/recipes-local/helloworld/files/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | while(1) { 7 | printf("Hello, world!\n"); 8 | sleep(10); 9 | } 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/recipes-local/helloworld/helloworld_1.0.bb: -------------------------------------------------------------------------------- 1 | DESCRIPTION = "A friendly program that prints Hello World!" 2 | PRIORITY = "optional" 3 | SECTION = "examples" 4 | 5 | LICENSE = "GPLv2" 6 | LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" 7 | 8 | SRC_URI = "file://helloworld.c" 9 | 10 | S = "${WORKDIR}" 11 | 12 | do_compile() { 13 | ${CC} ${CFLAGS} ${LDFLAGS} helloworld.c -o helloworld 14 | } 15 | 16 | do_install() { 17 | install -d ${D}${bindir} 18 | install -m 0755 helloworld ${D}${bindir} 19 | } 20 | -------------------------------------------------------------------------------- /Chapter06/poky/meta-nova/recipes-local/images/nova-image.bb: -------------------------------------------------------------------------------- 1 | require recipes-core/images/core-image-minimal.bb 2 | IMAGE_INSTALL += "helloworld strace" 3 | -------------------------------------------------------------------------------- /Chapter06/run-qemu-buildroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | KERNEL=output/images/zImage 4 | DTB=output/images/versatile-pb.dtb 5 | ROOTFS=output/images/rootfs.ext2 6 | 7 | if [ ! -f ${KERNEL} ]; then 8 | echo "${KERNEL} does not exist" 9 | exit 1 10 | fi 11 | if [ ! -f ${DTB} ]; then 12 | echo "${DTB} does not exist" 13 | exit 1 14 | fi 15 | 16 | qemu-system-arm -M versatilepb -m 256 \ 17 | -kernel ${KERNEL} \ 18 | -dtb ${DTB} \ 19 | -drive file=${ROOTFS},if=scsi,format=raw \ 20 | -append "root=/dev/sda console=ttyAMA0,115200" \ 21 | -serial stdio -net nic,model=rtl8139 -net user 22 | -------------------------------------------------------------------------------- /Chapter08/meta-ota/COPYING.MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Chapter08/meta-ota/README: -------------------------------------------------------------------------------- 1 | This README file contains information on the contents of the 2 | ota layer. 3 | 4 | Please see the corresponding sections below for details. 5 | 6 | 7 | Dependencies 8 | ============ 9 | 10 | This layer depends on: 11 | 12 | URI: git://git.openembedded.org/bitbake 13 | branch: master 14 | 15 | URI: git://git.openembedded.org/openembedded-core 16 | layers: meta 17 | branch: master 18 | 19 | URI: git://git.yoctoproject.org/xxxx 20 | layers: xxxx 21 | branch: master 22 | 23 | 24 | Patches 25 | ======= 26 | 27 | Please submit any patches against the ota layer to the 28 | xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer: 29 | 30 | Maintainer: XXX YYYYYY 31 | 32 | 33 | Table of Contents 34 | ================= 35 | 36 | I. Adding the ota layer to your build 37 | II. Misc 38 | 39 | 40 | I. Adding the ota layer to your build 41 | ================================================= 42 | 43 | --- replace with specific instructions for the ota layer --- 44 | 45 | In order to use this layer, you need to make the build system aware of 46 | it. 47 | 48 | Assuming the ota layer exists at the top-level of your 49 | yocto build tree, you can add it to the build system by adding the 50 | location of the ota layer to bblayers.conf, along with any 51 | other layers needed. e.g.: 52 | 53 | BBLAYERS ?= " \ 54 | /path/to/yocto/meta \ 55 | /path/to/yocto/meta-poky \ 56 | /path/to/yocto/meta-yocto-bsp \ 57 | /path/to/yocto/meta-ota \ 58 | " 59 | 60 | 61 | II. Misc 62 | ======== 63 | 64 | --- replace with specific information about the ota layer --- 65 | -------------------------------------------------------------------------------- /Chapter08/meta-ota/conf/layer.conf: -------------------------------------------------------------------------------- 1 | # We have a conf and classes directory, add to BBPATH 2 | BBPATH .= ":${LAYERDIR}" 3 | 4 | # We have recipes-* directories, add to BBFILES 5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ 6 | ${LAYERDIR}/recipes-*/*/*.bbappend" 7 | 8 | BBFILE_COLLECTIONS += "ota" 9 | BBFILE_PATTERN_ota = "^${LAYERDIR}/" 10 | BBFILE_PRIORITY_ota = "6" 11 | -------------------------------------------------------------------------------- /Chapter08/meta-ota/recipes-core/netbase/netbase_5.3.bbappend: -------------------------------------------------------------------------------- 1 | do_install_append () { 2 | echo "10.0.2.2 docker.mender.io s3.docker.mender.io" >> ${D}${sysconfdir}/hosts 3 | } 4 | -------------------------------------------------------------------------------- /Chapter09/dummy-driver/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # LINUXDIR should point to the kerenl you are running on the target. 4 | # If you are building with Buildroot, you would type something like: 5 | 6 | # export ARCH=arm 7 | # export CROSS_COMPILE=arm-buildroot-linux-gnueabi- 8 | # export LINUXDIR=/home/chris/buildroot/output/build/linux-4.9.6 9 | # make 10 | 11 | # If you are compiling with a Yocto Project SDK, everything should 12 | # be set up when you source the environment-setup scipt so you can 13 | # just type: 14 | 15 | # make 16 | 17 | LINUXDIR ?= $(SDKTARGETSYSROOT)/usr/src/kernel 18 | 19 | obj-m := dummy.o 20 | 21 | all: 22 | make -C $(LINUXDIR) M=$(shell pwd) 23 | 24 | clean: 25 | make -C $(LINUXDIR) M=$(shell pwd) clean 26 | 27 | -------------------------------------------------------------------------------- /Chapter09/dummy-driver/dummy.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- */ 2 | /* */ 3 | /* Dummy char driver */ 4 | /* */ 5 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 6 | /* */ 7 | /* This program is free software; you can redistribute it and/or modify */ 8 | /* it under the terms of the GNU General Public License as published by */ 9 | /* the Free Software Foundation; either version 2 of the License, or */ 10 | /* (at your option) any later version. */ 11 | /* */ 12 | /* This program is distributed in the hope that it will be useful, */ 13 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 14 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 15 | /* General Public License for more details. */ 16 | /* */ 17 | /* You should have received a copy of the GNU General Public License */ 18 | /* along with this program; if not, write to the Free Software */ 19 | /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 20 | /* */ 21 | /* ------------------------------------------------------------------------- */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define DEVICE_NAME "dummy" 30 | #define MAJOR_NUM 42 31 | #define NUM_DEVICES 4 32 | 33 | static struct class *dummy_class; 34 | 35 | static int dummy_open(struct inode *inode, struct file *file) 36 | { 37 | pr_info("%s\n", __func__); 38 | return 0; 39 | } 40 | 41 | static int dummy_release(struct inode *inode, struct file *file) 42 | { 43 | pr_info("%s\n", __func__); 44 | return 0; 45 | } 46 | 47 | static ssize_t dummy_read(struct file *file, 48 | char *buffer, size_t length, loff_t * offset) 49 | { 50 | pr_info("%s %u\n", __func__, length); 51 | return 0; 52 | } 53 | 54 | static ssize_t dummy_write(struct file *file, 55 | const char *buffer, size_t length, loff_t * offset) 56 | { 57 | pr_info("%s %u\n", __func__, length); 58 | return length; 59 | } 60 | 61 | struct file_operations dummy_fops = { 62 | .owner = THIS_MODULE, 63 | .open = dummy_open, 64 | .release = dummy_release, 65 | .read = dummy_read, 66 | .write = dummy_write, 67 | }; 68 | 69 | int __init dummy_init(void) 70 | { 71 | int ret; 72 | int i; 73 | 74 | printk("Dummy loaded\n"); 75 | ret = register_chrdev(MAJOR_NUM, DEVICE_NAME, &dummy_fops); 76 | if (ret != 0) 77 | return ret; 78 | 79 | dummy_class = class_create(THIS_MODULE, DEVICE_NAME); 80 | for (i = 0; i < NUM_DEVICES; i++) { 81 | device_create(dummy_class, NULL, 82 | MKDEV(MAJOR_NUM, i), NULL, "dummy%d", i); 83 | } 84 | 85 | return 0; 86 | } 87 | 88 | void __exit dummy_exit(void) 89 | { 90 | int i; 91 | 92 | for (i = 0; i < NUM_DEVICES; i++) { 93 | device_destroy(dummy_class, MKDEV(MAJOR_NUM, i)); 94 | } 95 | class_destroy(dummy_class); 96 | 97 | unregister_chrdev(MAJOR_NUM, DEVICE_NAME); 98 | printk("Dummy unloaded\n"); 99 | } 100 | 101 | module_init(dummy_init); 102 | module_exit(dummy_exit); 103 | MODULE_LICENSE("GPL"); 104 | MODULE_AUTHOR("Chris Simmonds"); 105 | MODULE_DESCRIPTION("A dummy driver"); 106 | -------------------------------------------------------------------------------- /Chapter09/gpio-int/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = gpio-int 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter09/gpio-int/config-gpio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Configure P9_15 (gpio1_16, aka gpio 48) is input, trigger on falling edge" 4 | echo 48 > /sys/class/gpio/export 5 | echo falling > /sys/class/gpio/gpio48/edge 6 | -------------------------------------------------------------------------------- /Chapter09/gpio-int/gpio-int.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /* 11 | * Demonstration of using poll(2) to wait for an interrupt on GPIO. 12 | * 13 | * To try this out on a BeagleBone Black, connect a push button switch 14 | * between P9 15 (gpio1_16) and P9 1 (ground). 15 | * 16 | * gpio1_15 is configured as gpio 48, so to make it an input which 17 | * triggers on a falling edge, write 18 | * 19 | * echo 48 > /sys/class/gpio/export 20 | * echo falling > /sys/class/gpio/gpio48/edge 21 | * 22 | * Now, the gpio1_15 pin is normally pulled high, so 23 | * /sys/class/gpio48/value reads as 1'. 24 | * Pushing the button takes it low, and value reads as '0'. 25 | * 26 | * This program waits for the level to fall from 1 to 0 and 27 | * prints out a message each time it does so. 28 | */ 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | int f; 33 | struct pollfd poll_fds[1]; 34 | int ret; 35 | char value[4]; 36 | int n; 37 | 38 | f = open("/sys/class/gpio/gpio48/value", O_RDONLY); 39 | if (f == -1) { 40 | perror("Can't open gpio48"); 41 | return 1; 42 | } 43 | 44 | n = read(f, &value, sizeof(value)); 45 | if (n > 0) { 46 | printf("Initial value value=%c\n", 47 | value[0]); 48 | lseek(f, 0, SEEK_SET); 49 | } 50 | 51 | poll_fds[0].fd = f; 52 | poll_fds[0].events = POLLPRI | POLLERR; 53 | while (1) { 54 | printf("Waiting\n"); 55 | ret = poll(poll_fds, 1, -1); 56 | if (ret > 0) { 57 | n = read(f, &value, sizeof(value)); 58 | printf("Button pressed: read %d bytes, value=%c\n", 59 | n, value[0]); 60 | lseek(f, 0, SEEK_SET); 61 | } 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Chapter09/i2c-example/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = i2c-eeprom-read 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter09/i2c-example/i2c-eeprom-read.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | /* 4 | * Sample program to read the first 4 bytes of the AT24C512B 5 | * 512 KiB EEPROM from the BeagleBone Black 6 | * The datasheet for the AT24C512B can be found at 7 | * http://www.atmel.com/Images/doc5297.pdf 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* Address of the EEPROM on the BeagleBone Black board */ 17 | #define I2C_ADDRESS 0x50 18 | 19 | int main(void) 20 | { 21 | int f; 22 | int n; 23 | char buf[10]; 24 | 25 | /* Open the adapter and set the address of the I2C device */ 26 | f = open("/dev/i2c-0", O_RDWR); 27 | if (f < 0) { 28 | perror("/dev/i2c-0:"); 29 | return 1; 30 | } 31 | 32 | /* Set the address of the i2c slave device */ 33 | if (ioctl(f, I2C_SLAVE, I2C_ADDRESS) == -1) { 34 | perror("ioctl I2C_SLAVE"); 35 | return 1; 36 | } 37 | 38 | /* Set the 16-bit address to read (0) */ 39 | buf[0] = 0; /* address byte 1 */ 40 | buf[1] = 0; /* address byte 2 */ 41 | n = write(f, buf, 2); 42 | if (n == -1) { 43 | perror("write"); 44 | return 1; 45 | } 46 | 47 | /* Now read 4 bytes from that address */ 48 | n = read(f, buf, 4); 49 | if (n == -1) { 50 | perror("read"); 51 | return 1; 52 | } 53 | printf("0x%x 0x%x0 0x%x 0x%x\n", 54 | buf[0], buf[1], buf[2], buf[3]); 55 | 56 | close(f); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter09/read-urandom/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = read-urandom 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter09/read-urandom/read-urandom.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | int f; 12 | unsigned int rnd; 13 | int n; 14 | 15 | f = open("/dev/urandom", O_RDONLY); 16 | if (f < 0) { 17 | perror("Failed to open urandom"); 18 | return 1; 19 | } 20 | n = read(f, &rnd, sizeof(rnd)); 21 | if (n != sizeof(rnd)) { 22 | perror("Problem reading urandom"); 23 | return 1; 24 | } 25 | printf("Random number = 0x%x\n", rnd); 26 | close(f); 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Chapter09/show-mac-addresses/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = show-mac-address 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter09/show-mac-addresses/show-mac-address.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int s; 14 | int ret; 15 | struct ifreq ifr; 16 | int i; 17 | if (argc != 2) { 18 | printf("Usage %s [network interface]\n", argv[0]); 19 | return 1; 20 | } 21 | s = socket(PF_INET, SOCK_DGRAM, 0); 22 | if (s < 0) { 23 | perror("socket"); 24 | return 1; 25 | } 26 | strcpy(ifr.ifr_name, argv[1]); 27 | ret = ioctl(s, SIOCGIFHWADDR, &ifr); 28 | if (ret < 0) { 29 | perror("ioctl"); 30 | return 1; 31 | } 32 | for (i = 0; i < 6; i++) 33 | printf("%02x:", (unsigned char)ifr.ifr_hwaddr.sa_data[i]); 34 | printf("\n"); 35 | close(s); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter10/simpleserver-systemd/simpleserver.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Simple server 3 | 4 | [Service] 5 | Type=forking 6 | ExecStart=/usr/bin/simpleserver 7 | 8 | [Install] 9 | WantedBy=multi-user.target 10 | 11 | -------------------------------------------------------------------------------- /Chapter10/simpleserver-sysvinit/init.d/simpleserver: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | case "$1" in 4 | start) 5 | echo "Starting simpelserver" 6 | start-stop-daemon -S -n simpleserver -a /usr/bin/simpleserver 7 | ;; 8 | stop) 9 | echo "Stopping simpleserver" 10 | start-stop-daemon -K -n simpleserver 11 | ;; 12 | *) 13 | echo "Usage: $0 {start|stop}" 14 | exit 1 15 | esac 16 | 17 | exit 0 18 | -------------------------------------------------------------------------------- /Chapter10/simpleserver/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = simpleserver 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter10/simpleserver/simpleserver.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static void sig_handler(int sig) 14 | { 15 | printf("Cleaning up\n"); 16 | } 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | time_t start; 21 | int f; 22 | char msg[64]; 23 | 24 | printf("%s starting\n", argv[0]); 25 | 26 | f = open("/dev/kmsg", O_WRONLY); 27 | if (f == -1) 28 | printf("Failed to open /dev/kmsg: no messages from me!\n"); 29 | 30 | if (argc == 2 && strcmp(argv[1], "-n") == 0) { 31 | printf("Not forking\n"); 32 | } else { 33 | printf("Deamonizing...\n"); 34 | if (daemon(0, 0) == -1) { 35 | perror("Daemon failed"); 36 | return 1; 37 | } 38 | } 39 | 40 | signal(SIGHUP, sig_handler); 41 | 42 | start = time(NULL); 43 | while(1) { 44 | snprintf(msg, sizeof(msg), "%s has been running for %ld seconds\n", 45 | argv[0], 46 | time(NULL) - start); 47 | write(f, msg, strlen(msg)); 48 | sleep(60); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter11/do-work/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = do-work 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter11/do-work/do-work.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static volatile int quit_now = 0; 12 | unsigned long loop_count; 13 | sigset_t alarm_sig; 14 | 15 | void sig_int_handler(int n) 16 | { 17 | quit_now = 1; 18 | } 19 | 20 | static unsigned long waste_time(unsigned long v) 21 | { 22 | unsigned long new_v; 23 | new_v = (v * 22)/7; 24 | return new_v; 25 | } 26 | 27 | static void calibrate(void) 28 | { 29 | struct itimerval value; 30 | struct sigaction act; 31 | int i; 32 | 33 | act.sa_handler = sig_int_handler; 34 | sigemptyset(&act.sa_mask); 35 | act.sa_flags = 0; 36 | sigaction(SIGALRM, &act, NULL); 37 | 38 | /* Create a 10ms timer */ 39 | value.it_value.tv_sec = 0; 40 | value.it_value.tv_usec = 10000; 41 | value.it_interval.tv_sec = 0; 42 | value.it_interval.tv_usec = 10000; 43 | if (setitimer(ITIMER_REAL, &value, NULL) != 0) { 44 | perror("Failed to set timer"); 45 | exit(1); 46 | } 47 | 48 | /* See how many times we loop in 10 ms. 49 | Let the timer expire 4 times and take the last count */ 50 | for (i = 0; i < 4; i++) { 51 | quit_now = 0; 52 | loop_count = 0; 53 | while (!quit_now) { 54 | waste_time(123); 55 | loop_count++; 56 | } 57 | } 58 | } 59 | 60 | static void do_work(long msecs) 61 | { 62 | unsigned long local_count; 63 | unsigned long end_count; 64 | 65 | local_count = 0; 66 | end_count = (loop_count * msecs)/10; 67 | while (local_count < end_count) { 68 | waste_time(123); 69 | local_count++; 70 | } 71 | } 72 | 73 | static void wait_next(long msecs) 74 | { 75 | int sig; 76 | sigwait(&alarm_sig, &sig); 77 | } 78 | 79 | static void usage(void) 80 | { 81 | printf("Usage: \n" 82 | " -c calibrate: you need to do this first\n" 83 | " -l [loop count] loop count from calibration\n" 84 | " -n [on count] on (work) time in ms, default 10\n" 85 | " -f [off count] off (sleep) time, default same as on time\n"); 86 | } 87 | 88 | int main(int argc, char *argv[]) 89 | { 90 | int opt; 91 | unsigned long on_time_ms = 10; 92 | unsigned long off_time_ms = -1; 93 | struct itimerval value; 94 | 95 | if (argc == 1) { 96 | usage(); 97 | exit(0); 98 | } 99 | 100 | while ((opt = getopt(argc, argv, "cf:l:n:")) != -1) { 101 | switch (opt) { 102 | case 'c': 103 | printf("Calibrating...\n"); 104 | calibrate(); 105 | printf("Now run %s -l %lu\n", argv[0], loop_count); 106 | exit(0); 107 | break; 108 | case 'f': 109 | off_time_ms = strtoul(optarg, NULL, 0); 110 | break; 111 | case 'l': 112 | loop_count = strtoul(optarg, NULL, 0); 113 | break; 114 | case 'n': 115 | on_time_ms = strtoul(optarg, NULL, 0); 116 | break; 117 | default: 118 | usage(); 119 | exit(0); 120 | } 121 | } 122 | 123 | if (loop_count == 0) { 124 | usage(); 125 | exit(0); 126 | } 127 | 128 | if (off_time_ms == -1) 129 | off_time_ms = on_time_ms; 130 | 131 | printf("working for %lu ms, sleeping for %lu ms\n", 132 | on_time_ms, off_time_ms); 133 | 134 | /* Block SIGALRM */ 135 | sigemptyset (&alarm_sig); 136 | sigaddset (&alarm_sig, SIGALRM); 137 | sigprocmask (SIG_BLOCK, &alarm_sig, NULL); 138 | 139 | /* Create a timer */ 140 | value.it_value.tv_sec = 0; 141 | value.it_value.tv_usec = (off_time_ms + on_time_ms) * 1000; 142 | value.it_interval.tv_sec = 0; 143 | value.it_interval.tv_usec = (off_time_ms + on_time_ms) * 1000; 144 | if (setitimer(ITIMER_REAL, &value, NULL) != 0) { 145 | perror("Failed to set timer"); 146 | exit(1); 147 | } 148 | while (1) { 149 | do_work(on_time_ms); 150 | wait_next(off_time_ms); 151 | } 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /Chapter11/poky/build-bbb/conf/local.conf: -------------------------------------------------------------------------------- 1 | # 2 | # This file is your local configuration file and is where all local user settings 3 | # are placed. The comments in this file give some guide to the options a new user 4 | # to the system might want to change but pretty much any configuration option can 5 | # be set in this file. More adventurous users can look at local.conf.extended 6 | # which contains other examples of configuration which can be placed in this file 7 | # but new users likely won't need any of them initially. 8 | # 9 | # Lines starting with the '#' character are commented out and in some cases the 10 | # default values are provided as comments to show people example syntax. Enabling 11 | # the option is a question of removing the # character and making any change to the 12 | # variable as required. 13 | 14 | MACHINE = "beaglebone" 15 | 16 | # Select the TI kernel, which has power management support 17 | # for the AM335x SoCs 18 | PREFERRED_PROVIDER_virtual/kernel = "ti-linux-kernel" 19 | IMAGE_INSTALL_append = " powertop strace dropbear rt-tests amx3-cm3 gdbserver kernel-vmlinux" 20 | 21 | # 22 | # Machine Selection 23 | # 24 | # You need to select a specific machine to target the build with. There are a selection 25 | # of emulated machines available which can boot and run in the QEMU emulator: 26 | # 27 | #MACHINE ?= "qemuarm" 28 | #MACHINE ?= "qemuarm64" 29 | #MACHINE ?= "qemumips" 30 | #MACHINE ?= "qemumips64" 31 | #MACHINE ?= "qemuppc" 32 | #MACHINE ?= "qemux86" 33 | #MACHINE ?= "qemux86-64" 34 | # 35 | # There are also the following hardware board target machines included for 36 | # demonstration purposes: 37 | # 38 | #MACHINE ?= "beaglebone" 39 | #MACHINE ?= "genericx86" 40 | #MACHINE ?= "genericx86-64" 41 | #MACHINE ?= "mpc8315e-rdb" 42 | #MACHINE ?= "edgerouter" 43 | # 44 | # This sets the default machine to be qemux86 if no other machine is selected: 45 | MACHINE ??= "qemux86" 46 | 47 | # 48 | # Where to place downloads 49 | # 50 | # During a first build the system will download many different source code tarballs 51 | # from various upstream projects. This can take a while, particularly if your network 52 | # connection is slow. These are all stored in DL_DIR. When wiping and rebuilding you 53 | # can preserve this directory to speed up this part of subsequent builds. This directory 54 | # is safe to share between multiple builds on the same machine too. 55 | # 56 | # The default is a downloads directory under TOPDIR which is the build directory. 57 | # 58 | #DL_DIR ?= "${TOPDIR}/downloads" 59 | 60 | # 61 | # Where to place shared-state files 62 | # 63 | # BitBake has the capability to accelerate builds based on previously built output. 64 | # This is done using "shared state" files which can be thought of as cache objects 65 | # and this option determines where those files are placed. 66 | # 67 | # You can wipe out TMPDIR leaving this directory intact and the build would regenerate 68 | # from these files if no changes were made to the configuration. If changes were made 69 | # to the configuration, only shared state files where the state was still valid would 70 | # be used (done using checksums). 71 | # 72 | # The default is a sstate-cache directory under TOPDIR. 73 | # 74 | #SSTATE_DIR ?= "${TOPDIR}/sstate-cache" 75 | 76 | # 77 | # Where to place the build output 78 | # 79 | # This option specifies where the bulk of the building work should be done and 80 | # where BitBake should place its temporary files and output. Keep in mind that 81 | # this includes the extraction and compilation of many applications and the toolchain 82 | # which can use Gigabytes of hard disk space. 83 | # 84 | # The default is a tmp directory under TOPDIR. 85 | # 86 | #TMPDIR = "${TOPDIR}/tmp" 87 | 88 | # 89 | # Default policy config 90 | # 91 | # The distribution setting controls which policy settings are used as defaults. 92 | # The default value is fine for general Yocto project use, at least initially. 93 | # Ultimately when creating custom policy, people will likely end up subclassing 94 | # these defaults. 95 | # 96 | DISTRO ?= "poky" 97 | # As an example of a subclass there is a "bleeding" edge policy configuration 98 | # where many versions are set to the absolute latest code from the upstream 99 | # source control systems. This is just mentioned here as an example, its not 100 | # useful to most new users. 101 | # DISTRO ?= "poky-bleeding" 102 | 103 | # 104 | # Package Management configuration 105 | # 106 | # This variable lists which packaging formats to enable. Multiple package backends 107 | # can be enabled at once and the first item listed in the variable will be used 108 | # to generate the root filesystems. 109 | # Options are: 110 | # - 'package_deb' for debian style deb files 111 | # - 'package_ipk' for ipk files are used by opkg (a debian style embedded package manager) 112 | # - 'package_rpm' for rpm style packages 113 | # E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk" 114 | # We default to rpm: 115 | PACKAGE_CLASSES ?= "package_rpm" 116 | 117 | # 118 | # SDK target architecture 119 | # 120 | # This variable specifies the architecture to build SDK items for and means 121 | # you can build the SDK packages for architectures other than the machine you are 122 | # running the build on (i.e. building i686 packages on an x86_64 host). 123 | # Supported values are i686 and x86_64 124 | #SDKMACHINE ?= "i686" 125 | 126 | # 127 | # Extra image configuration defaults 128 | # 129 | # The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated 130 | # images. Some of these options are added to certain image types automatically. The 131 | # variable can contain the following options: 132 | # "dbg-pkgs" - add -dbg packages for all installed packages 133 | # (adds symbol information for debugging/profiling) 134 | # "dev-pkgs" - add -dev packages for all installed packages 135 | # (useful if you want to develop against libs in the image) 136 | # "ptest-pkgs" - add -ptest packages for all ptest-enabled packages 137 | # (useful if you want to run the package test suites) 138 | # "tools-sdk" - add development tools (gcc, make, pkgconfig etc.) 139 | # "tools-debug" - add debugging tools (gdb, strace) 140 | # "eclipse-debug" - add Eclipse remote debugging support 141 | # "tools-profile" - add profiling tools (oprofile, lttng, valgrind) 142 | # "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.) 143 | # "debug-tweaks" - make an image suitable for development 144 | # e.g. ssh root access has a blank password 145 | # There are other application targets that can be used here too, see 146 | # meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details. 147 | # We default to enabling the debugging tweaks. 148 | EXTRA_IMAGE_FEATURES ?= "debug-tweaks" 149 | 150 | # 151 | # Additional image features 152 | # 153 | # The following is a list of additional classes to use when building images which 154 | # enable extra features. Some available options which can be included in this variable 155 | # are: 156 | # - 'buildstats' collect build statistics 157 | # - 'image-mklibs' to reduce shared library files size for an image 158 | # - 'image-prelink' in order to prelink the filesystem image 159 | # - 'image-swab' to perform host system intrusion detection 160 | # NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink 161 | # NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended 162 | USER_CLASSES ?= "buildstats image-mklibs image-prelink" 163 | 164 | # 165 | # Runtime testing of images 166 | # 167 | # The build system can test booting virtual machine images under qemu (an emulator) 168 | # after any root filesystems are created and run tests against those images. To 169 | # enable this uncomment this line. See classes/testimage(-auto).bbclass for 170 | # further details. 171 | #TEST_IMAGE = "1" 172 | # 173 | # Interactive shell configuration 174 | # 175 | # Under certain circumstances the system may need input from you and to do this it 176 | # can launch an interactive shell. It needs to do this since the build is 177 | # multithreaded and needs to be able to handle the case where more than one parallel 178 | # process may require the user's attention. The default is iterate over the available 179 | # terminal types to find one that works. 180 | # 181 | # Examples of the occasions this may happen are when resolving patches which cannot 182 | # be applied, to use the devshell or the kernel menuconfig 183 | # 184 | # Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none 185 | # Note: currently, Konsole support only works for KDE 3.x due to the way 186 | # newer Konsole versions behave 187 | #OE_TERMINAL = "auto" 188 | # By default disable interactive patch resolution (tasks will just fail instead): 189 | PATCHRESOLVE = "noop" 190 | 191 | # 192 | # Disk Space Monitoring during the build 193 | # 194 | # Monitor the disk space during the build. If there is less that 1GB of space or less 195 | # than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully 196 | # shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort 197 | # of the build. The reason for this is that running completely out of space can corrupt 198 | # files and damages the build in ways which may not be easily recoverable. 199 | # It's necesary to monitor /tmp, if there is no space left the build will fail 200 | # with very exotic errors. 201 | BB_DISKMON_DIRS = "\ 202 | STOPTASKS,${TMPDIR},1G,100K \ 203 | STOPTASKS,${DL_DIR},1G,100K \ 204 | STOPTASKS,${SSTATE_DIR},1G,100K \ 205 | STOPTASKS,/tmp,100M,100K \ 206 | ABORT,${TMPDIR},100M,1K \ 207 | ABORT,${DL_DIR},100M,1K \ 208 | ABORT,${SSTATE_DIR},100M,1K \ 209 | ABORT,/tmp,10M,1K" 210 | 211 | # 212 | # Shared-state files from other locations 213 | # 214 | # As mentioned above, shared state files are prebuilt cache data objects which can 215 | # used to accelerate build time. This variable can be used to configure the system 216 | # to search other mirror locations for these objects before it builds the data itself. 217 | # 218 | # This can be a filesystem directory, or a remote url such as http or ftp. These 219 | # would contain the sstate-cache results from previous builds (possibly from other 220 | # machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the 221 | # cache locations to check for the shared objects. 222 | # NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH 223 | # at the end as shown in the examples below. This will be substituted with the 224 | # correct path within the directory structure. 225 | #SSTATE_MIRRORS ?= "\ 226 | #file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \ 227 | #file://.* file:///some/local/dir/sstate/PATH" 228 | 229 | 230 | # 231 | # Qemu configuration 232 | # 233 | # By default qemu will build with a builtin VNC server where graphical output can be 234 | # seen. The two lines below enable the SDL backend too. By default libsdl-native will 235 | # be built, if you want to use your host's libSDL instead of the minimal libsdl built 236 | # by libsdl-native then uncomment the ASSUME_PROVIDED line below. 237 | PACKAGECONFIG_append_pn-qemu-native = " sdl" 238 | PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl" 239 | #ASSUME_PROVIDED += "libsdl-native" 240 | 241 | # CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to 242 | # track the version of this file when it was generated. This can safely be ignored if 243 | # this doesn't mean anything to you. 244 | CONF_VERSION = "1" 245 | -------------------------------------------------------------------------------- /Chapter11/poky/meta-bbb-pm/COPYING.MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Chapter11/poky/meta-bbb-pm/README: -------------------------------------------------------------------------------- 1 | This README file contains information on the contents of the 2 | nova layer. 3 | 4 | Please see the corresponding sections below for details. 5 | 6 | 7 | Dependencies 8 | ============ 9 | 10 | This layer depends on: 11 | 12 | URI: git://git.openembedded.org/bitbake 13 | branch: master 14 | 15 | URI: git://git.openembedded.org/openembedded-core 16 | layers: meta 17 | branch: master 18 | 19 | URI: git://git.yoctoproject.org/xxxx 20 | layers: xxxx 21 | branch: master 22 | 23 | 24 | Patches 25 | ======= 26 | 27 | Please submit any patches against the nova layer to the 28 | xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer: 29 | 30 | Maintainer: XXX YYYYYY 31 | 32 | 33 | Table of Contents 34 | ================= 35 | 36 | I. Adding the nova layer to your build 37 | II. Misc 38 | 39 | 40 | I. Adding the nova layer to your build 41 | ================================================= 42 | 43 | --- replace with specific instructions for the nova layer --- 44 | 45 | In order to use this layer, you need to make the build system aware of 46 | it. 47 | 48 | Assuming the nova layer exists at the top-level of your 49 | yocto build tree, you can add it to the build system by adding the 50 | location of the nova layer to bblayers.conf, along with any 51 | other layers needed. e.g.: 52 | 53 | BBLAYERS ?= " \ 54 | /path/to/yocto/meta \ 55 | /path/to/yocto/meta-poky \ 56 | /path/to/yocto/meta-yocto-bsp \ 57 | /path/to/yocto/meta-nova \ 58 | " 59 | 60 | 61 | II. Misc 62 | ======== 63 | 64 | --- replace with specific information about the nova layer --- 65 | -------------------------------------------------------------------------------- /Chapter11/poky/meta-bbb-pm/conf/layer.conf: -------------------------------------------------------------------------------- 1 | # We have a conf and classes directory, add to BBPATH 2 | BBPATH .= ":${LAYERDIR}" 3 | 4 | # We have recipes-* directories, add to BBFILES 5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ 6 | ${LAYERDIR}/recipes-*/*/*.bbappend" 7 | 8 | BBFILE_COLLECTIONS += "nova" 9 | BBFILE_PATTERN_nova = "^${LAYERDIR}/" 10 | BBFILE_PRIORITY_nova = "6" 11 | -------------------------------------------------------------------------------- /Chapter11/poky/meta-bbb-pm/recipes-bsp/cm3-pm-firmware/amx3-cm3_git.bb: -------------------------------------------------------------------------------- 1 | DESCRIPTION = "Cortex-M3 binary blob for suspend-resume" 2 | 3 | LICENSE = "TI-TSPA" 4 | LIC_FILES_CHKSUM = "file://License.txt;md5=7bdc54a749ab7a7dea999d25d99a41b8" 5 | 6 | PV = "1.9.2" 7 | PR = "r0" 8 | 9 | SRCREV = "7eb9c0856a9e8b3b42bf64f761da135852b8eea7" 10 | BRANCH ?= "ti-v4.1.y" 11 | 12 | SRC_URI = "git://git.ti.com/processor-firmware/ti-amx3-cm3-pm-firmware.git;protocol=git;branch=${BRANCH}" 13 | 14 | S = "${WORKDIR}/git" 15 | 16 | FLOATABI = "${@bb.utils.contains("TUNE_FEATURES", "vfp", bb.utils.contains("TUNE_FEATURES", "callconvention-hard", " -mfloat-abi=hard", " -mfloat-abi=softfp", d), "" ,d)}" 17 | 18 | do_compile() { 19 | make CROSS_COMPILE="${TARGET_PREFIX}" CC="${TARGET_PREFIX}gcc ${TOOLCHAIN_OPTIONS} ${FLOATABI}" 20 | } 21 | 22 | do_install() { 23 | install -d ${D}${base_libdir}/firmware 24 | install -m 0644 bin/am335x-pm-firmware.elf ${D}${base_libdir}/firmware/ 25 | install -m 0644 bin/*-scale-data.bin ${D}${base_libdir}/firmware/ 26 | } 27 | 28 | FILES_${PN} += "${base_libdir}/firmware" 29 | -------------------------------------------------------------------------------- /Chapter11/poky/meta-bbb-pm/recipes-kernel/linux/ti-linux-kernel_4.1.bb: -------------------------------------------------------------------------------- 1 | # Recipe for ti-linux-kernel, with some customization to enable 2 | # power management features on settings for AM335x/Beaglebone 3 | 4 | inherit kernel 5 | require recipes-kernel/linux/linux-yocto.inc 6 | 7 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-4.1:" 8 | 9 | # Add run-time dependency for PM firmware to the rootfs 10 | DEPENDS = " amx3-cm3" 11 | 12 | KERNEL_DEVICETREE_ti33x = "am335x-boneblack.dtb" 13 | 14 | # Select 4.1 because later versions seem to have lost some 15 | # features 16 | LINUX_VERSION ?= "4.1" 17 | 18 | COMPATIBLE_MACHINE = "beaglebone" 19 | 20 | S = "${WORKDIR}/git" 21 | 22 | BRANCH = "ti-linux-4.1.y" 23 | 24 | SRCREV = "b56fa3bd73d45ef31478b7e3ab97570a0dd79c44" 25 | PV = "4.1.37+git${SRCPV}" 26 | 27 | # Append to the MACHINE_KERNEL_PR so that a new SRCREV will cause a rebuild 28 | MACHINE_KERNEL_PR_append = "a" 29 | PR = "${MACHINE_KERNEL_PR}" 30 | 31 | KERNEL_GIT_URI = "git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git" 32 | KERNEL_GIT_PROTOCOL = "git" 33 | SRC_URI += "${KERNEL_GIT_URI};protocol=${KERNEL_GIT_PROTOCOL};branch=${BRANCH} \ 34 | file://defconfig" 35 | 36 | # Copy the PMIC firmware into the kernel source so that it can be 37 | # built in to the kernel image. 38 | # This is not an elegant solution; but it works 39 | do_compile_prepend() { 40 | cp ${STAGING_DIR_HOST}/lib/firmware/am335x-pm-firmware.elf ${STAGING_KERNEL_DIR}/firmware 41 | cp ${STAGING_DIR_HOST}/lib/firmware/am335x-bone-scale-data.bin ${STAGING_KERNEL_DIR}/firmware 42 | } 43 | -------------------------------------------------------------------------------- /Chapter11/sysvinit-ondemand.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: ondemand 4 | # Required-Start: $remote_fs $all 5 | # Required-Stop: 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 8 | # Short-Description: Set the CPU Frequency Scaling governor to "ondemand" 9 | ### END INIT INFO 10 | 11 | # Don't run if we're going to start an Android LXC container: 12 | [ ! -f /etc/init/lxc-android-config.conf ] || exit 0 13 | 14 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 15 | 16 | . /lib/init/vars.sh 17 | . /lib/lsb/init-functions 18 | 19 | AVAILABLE="/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors" 20 | DOWN_FACTOR="/sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor" 21 | 22 | case "$1" in 23 | start) 24 | start-stop-daemon --start --background --exec /etc/init.d/ondemand -- background 25 | ;; 26 | background) 27 | sleep 60 # probably enough time for desktop login 28 | 29 | [ -f $AVAILABLE ] || exit 0 30 | read governors < $AVAILABLE 31 | case $governors in 32 | *interactive*) 33 | GOVERNOR="interactive" 34 | break 35 | ;; 36 | *ondemand*) 37 | GOVERNOR="ondemand" 38 | case $(uname -m) in 39 | ppc64*) 40 | SAMPLING=100 41 | ;; 42 | esac 43 | break 44 | ;; 45 | *powersave*) 46 | GOVERNOR="powersave" 47 | break 48 | ;; 49 | *) 50 | exit 0 51 | ;; 52 | esac 53 | 54 | for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 55 | do 56 | [ -f $CPUFREQ ] || continue 57 | echo -n $GOVERNOR > $CPUFREQ 58 | done 59 | if [ -n "$SAMPLING" ] && [ -f $DOWN_FACTOR ]; then 60 | echo -n $SAMPLING > $DOWN_FACTOR 61 | fi 62 | ;; 63 | restart|reload|force-reload) 64 | echo "Error: argument '$1' not supported" >&2 65 | exit 3 66 | ;; 67 | stop) 68 | ;; 69 | *) 70 | echo "Usage: $0 start|stop" >&2 71 | exit 3 72 | ;; 73 | esac 74 | -------------------------------------------------------------------------------- /Chapter12/condvar-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g -pthread 7 | PROGRAM = condvar-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/condvar-demo/condvar-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | char g_data[128]; 10 | pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 11 | pthread_mutex_t mutx = PTHREAD_MUTEX_INITIALIZER; 12 | 13 | void *consumer(void *arg) 14 | { 15 | while (1) { 16 | pthread_mutex_lock(&mutx); 17 | while (strlen(g_data) == 0) 18 | pthread_cond_wait(&cv, &mutx); 19 | 20 | /* Got data */ 21 | printf("%s\n", g_data); 22 | /* Truncate to null string again */ 23 | g_data[0] = 0; 24 | pthread_mutex_unlock(&mutx); 25 | } 26 | return NULL; 27 | } 28 | 29 | void *producer(void *arg) 30 | { 31 | int i = 0; 32 | 33 | while (1) { 34 | sleep(1); 35 | pthread_mutex_lock(&mutx); 36 | sprintf(g_data, "Data item %d", i); 37 | pthread_mutex_unlock(&mutx); 38 | pthread_cond_signal(&cv); 39 | i++; 40 | } 41 | return NULL; 42 | } 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | pthread_t producer_thread; 47 | pthread_t consumer_thread; 48 | 49 | pthread_create(&producer_thread, NULL, producer, NULL); 50 | pthread_create(&consumer_thread, NULL, consumer, NULL); 51 | 52 | /* Wait for both threads to finish */ 53 | pthread_join(producer_thread, NULL); 54 | pthread_join(consumer_thread, NULL); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Chapter12/exec-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = exec-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/exec-demo/exec-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | char command_str[128]; 13 | int pid; 14 | int child_status; 15 | int wait_for = 1; 16 | 17 | while (1) { 18 | printf("sh> "); 19 | scanf("%s", command_str); 20 | pid = fork(); 21 | if (pid == 0) { 22 | /* child */ 23 | printf("cmd '%s'\n", command_str); 24 | execl(command_str, command_str, (char *)NULL); 25 | /* We should not return from execl, so only get 26 | to this line if it failed */ 27 | perror("exec"); 28 | exit(1); 29 | } 30 | if (wait_for) { 31 | waitpid(pid, &child_status, 0); 32 | printf("Done, status %d\n", child_status); 33 | } 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Chapter12/fork-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = fork-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/fork-demo/fork-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | int pid; 12 | int status; 13 | pid = fork(); 14 | if (pid == 0) { 15 | printf("I am the child, PID %d\n", getpid()); 16 | sleep(10); 17 | exit(42); 18 | } else if (pid > 0) { 19 | printf("I am the parent, PID %d\n", getpid()); 20 | wait(&status); 21 | printf("Child terminated, status %d\n", WEXITSTATUS(status)); 22 | } else 23 | perror("fork:"); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /Chapter12/shared-mem-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g -lrt -pthread 7 | PROGRAM = shared-mem-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $^ $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/shared-mem-demo/shared-mem-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include /* For mode constants */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #define SHM_SEGMENT_SIZE 65536 14 | #define SHM_SEGMENT_NAME "/demo-shm" 15 | #define SEMA_NAME "/demo-sem" 16 | 17 | static sem_t *demo_sem; 18 | 19 | /* 20 | * If the shared memory segment does not exist already, create it 21 | * Returns a pointer to the segment or NULL if there is an error 22 | */ 23 | static void *get_shared_memory(void) 24 | { 25 | int shm_fd; 26 | struct shared_data *shm_p; 27 | /* Attempt to create the shared memory segment */ 28 | shm_fd = shm_open(SHM_SEGMENT_NAME, O_CREAT | O_EXCL | O_RDWR, 0666); 29 | if (shm_fd > 0) { 30 | /* succeeded: expand it to the desired size (Note: dont't do 31 | "this every time because ftruncate fills it with zeros) */ 32 | printf("Creating shared memory and setting size=%d\n", 33 | SHM_SEGMENT_SIZE); 34 | 35 | if (ftruncate(shm_fd, SHM_SEGMENT_SIZE) < 0) { 36 | perror("ftruncate"); 37 | exit(1); 38 | } 39 | /* Create a semaphore as well */ 40 | demo_sem = sem_open(SEMA_NAME, O_RDWR | O_CREAT, 0666, 1); 41 | 42 | if (demo_sem == SEM_FAILED) 43 | perror("sem_open failed\n"); 44 | } else if (shm_fd == -1 && errno == EEXIST) { 45 | /* Already exists: open again without O_CREAT */ 46 | shm_fd = shm_open(SHM_SEGMENT_NAME, O_RDWR, 0); 47 | demo_sem = sem_open(SEMA_NAME, O_RDWR); 48 | 49 | if (demo_sem == SEM_FAILED) 50 | perror("sem_open failed\n"); 51 | } 52 | 53 | if (shm_fd == -1) { 54 | perror("shm_open " SHM_SEGMENT_NAME); 55 | exit(1); 56 | } 57 | /* Map the shared memory */ 58 | shm_p = mmap(NULL, SHM_SEGMENT_SIZE, PROT_READ | PROT_WRITE, 59 | MAP_SHARED, shm_fd, 0); 60 | 61 | if (shm_p == NULL) { 62 | perror("mmap"); 63 | exit(1); 64 | } 65 | return shm_p; 66 | } 67 | 68 | int main(int argc, char *argv[]) 69 | { 70 | char *shm_p; 71 | printf("%s PID=%d\n", argv[0], getpid()); 72 | shm_p = get_shared_memory(); 73 | 74 | while (1) { 75 | printf("Press enter to see the current contents of shm\n"); 76 | getchar(); 77 | sem_wait(demo_sem); 78 | printf("%s\n", shm_p); 79 | /* Write our signature to the shared memory */ 80 | sprintf(shm_p, "Hello from process %d\n", getpid()); 81 | sem_post(demo_sem); 82 | } 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /Chapter12/thread-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g -pthread 7 | PROGRAM = thread-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter12/thread-demo/thread-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static void *thread_fn(void *arg) 9 | { 10 | printf("New thread started, PID %d TID %d\n", 11 | getpid(), (pid_t)syscall(SYS_gettid)); 12 | sleep(10); 13 | printf("New thread terminating\n"); 14 | return NULL; 15 | } 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | pthread_t t; 20 | 21 | printf("Main thread, PID %d TID %d\n", 22 | getpid(), (pid_t)syscall(SYS_gettid)); 23 | pthread_create(&t, NULL, thread_fn, NULL); 24 | pthread_join(t, NULL); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Chapter13/pagefault-demo/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # If cross-compiling, CC must point to your cross compiler, for example: 4 | # make CC=arm-linux-gnueabihf-gcc 5 | 6 | LOCAL_CFLAGS ?= -Wall -g 7 | PROGRAM = pagefault-demo 8 | 9 | $(PROGRAM): $(PROGRAM).c 10 | $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(LDFLAGS) $^ -o $@ 11 | 12 | clean: 13 | rm -f $(PROGRAM) 14 | 15 | -------------------------------------------------------------------------------- /Chapter13/pagefault-demo/pagefault-demo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define BUFFER_SIZE (1024 * 1024) 8 | 9 | void print_pgfaults(void) 10 | { 11 | int ret; 12 | struct rusage usage; 13 | ret = getrusage(RUSAGE_SELF, &usage); 14 | if (ret == -1) { 15 | perror("getrusage"); 16 | } else { 17 | printf("Major page faults %ld\n", usage.ru_majflt); 18 | printf("Minor page faults %ld\n", usage.ru_minflt); 19 | } 20 | } 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | unsigned char *p; 25 | printf("Initial state\n"); 26 | print_pgfaults(); 27 | p = malloc(BUFFER_SIZE); 28 | printf("After malloc\n"); 29 | print_pgfaults(); 30 | memset(p, 0x42, BUFFER_SIZE); 31 | printf("After memset\n"); 32 | print_pgfaults(); 33 | memset(p, 0x42, BUFFER_SIZE); 34 | printf("After 2nd memset\n"); 35 | print_pgfaults(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter14/mbx-driver-oops/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) 2 | # 3 | # LINUXDIR should point to the kerenl you are running on the target. 4 | # If you are building with Buildroot, you would type something like: 5 | 6 | # export ARCH=arm 7 | # export CROSS_COMPILE=arm-buildroot-linux-gnueabi- 8 | # export LINUXDIR=/home/chris/buildroot/output/build/linux-4.9.6 9 | # make 10 | 11 | # If you are compiling with a Yocto Project SDK, everything should 12 | # be set up when you source the environment-setup scipt so you can 13 | # just type: 14 | 15 | # make 16 | 17 | LINUXDIR ?= $(SDKTARGETSYSROOT)/usr/src/kernel 18 | 19 | obj-m := mbx.o 20 | 21 | all: 22 | make KCFLAGS="-O1 -fno-inline" -C $(LINUXDIR) M=$(shell pwd) 23 | 24 | clean: 25 | make -C $(LINUXDIR) M=$(shell pwd) clean 26 | 27 | -------------------------------------------------------------------------------- /Chapter14/mbx-driver-oops/mbx.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- */ 2 | /* */ 3 | /* Mailbox driver */ 4 | /* */ 5 | /* Copyright (C) 2017, Chris Simmonds (chris@2net.co.uk) */ 6 | /* */ 7 | /* This program is free software; you can redistribute it and/or modify */ 8 | /* it under the terms of the GNU General Public License as published by */ 9 | /* the Free Software Foundation; either version 2 of the License, or */ 10 | /* (at your option) any later version. */ 11 | /* */ 12 | /* This program is distributed in the hope that it will be useful, */ 13 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 14 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 15 | /* General Public License for more details. */ 16 | /* */ 17 | /* You should have received a copy of the GNU General Public License */ 18 | /* along with this program; if not, write to the Free Software */ 19 | /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 20 | /* */ 21 | /* ------------------------------------------------------------------------- */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #define DEVICE_NAME "mbx" 34 | #define MAJOR_NUM 42 35 | #define NUM_MAILBOXES 4 36 | #define MBX_LEN 1024 37 | 38 | /* Define this macro to cause an oops on read or write */ 39 | #define GO_OOPS 1 40 | 41 | struct mbx_data { 42 | char *mbx; 43 | int mbx_len; 44 | wait_queue_head_t wq; 45 | }; 46 | 47 | static struct mbx_data mailboxes[NUM_MAILBOXES]; 48 | static struct class *mbx_class; 49 | 50 | static int mbx_open(struct inode *inode, struct file *file) 51 | { 52 | if (MINOR(inode->i_rdev) >= NUM_MAILBOXES) { 53 | printk("Invalid mbx minor number\n"); 54 | return -ENODEV; 55 | } 56 | #ifndef GO_OOPS 57 | file->private_data = &mailboxes[MINOR(inode->i_rdev)]; 58 | #endif 59 | return 0; 60 | } 61 | 62 | static int mbx_release(struct inode *inode, struct file *file) 63 | { 64 | return 0; 65 | } 66 | 67 | static ssize_t mbx_read(struct file *file, 68 | char *buffer, size_t length, loff_t * offset) 69 | { 70 | struct mbx_data *m = (struct mbx_data *)file->private_data; 71 | int len; 72 | int ret; 73 | 74 | if (m->mbx_len == 0) { 75 | if (file->f_flags & O_NONBLOCK) 76 | return -EAGAIN; 77 | ret = wait_event_interruptible(m->wq, m->mbx_len > 0); 78 | if (ret != 0) { 79 | return ret; 80 | } 81 | } 82 | 83 | len = m->mbx_len; 84 | if (len > length) 85 | len = length; 86 | if (copy_to_user(buffer, m->mbx, m->mbx_len) != 0) { 87 | printk("copy_to_user failed\n"); 88 | return -EFAULT; 89 | } 90 | m->mbx_len = 0; 91 | return len; 92 | } 93 | 94 | static ssize_t mbx_write(struct file *file, 95 | const char *buffer, size_t length, loff_t * offset) 96 | { 97 | struct mbx_data *m = (struct mbx_data *)file->private_data; 98 | 99 | if (length > MBX_LEN) 100 | length = MBX_LEN; 101 | m->mbx_len = length; 102 | if (copy_from_user(m->mbx, buffer, length) != 0) { 103 | printk("copy_from_user failed\n"); 104 | return -EFAULT; 105 | } 106 | wake_up_interruptible(&m->wq); 107 | return length; 108 | } 109 | 110 | static unsigned int mbx_poll(struct file *file, poll_table * wait) 111 | { 112 | struct mbx_data *m = (struct mbx_data *)file->private_data; 113 | unsigned int mask = 0; 114 | 115 | poll_wait(file, &m->wq, wait); 116 | 117 | /* See if there is any data to read */ 118 | if (m->mbx_len > 0) 119 | mask |= (POLLIN | POLLRDNORM); 120 | 121 | /* Writing is always possible */ 122 | mask |= (POLLOUT | POLLWRNORM); 123 | 124 | return mask; 125 | } 126 | 127 | static long mbx_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 128 | { 129 | int ret = 0; 130 | 131 | return ret; 132 | } 133 | 134 | struct file_operations mbx_fops = { 135 | .owner = THIS_MODULE, 136 | .open = mbx_open, 137 | .release = mbx_release, 138 | .read = mbx_read, 139 | .write = mbx_write, 140 | .poll = mbx_poll, 141 | .unlocked_ioctl = mbx_ioctl 142 | }; 143 | 144 | int __init mbx_init(void) 145 | { 146 | int ret; 147 | int i; 148 | 149 | printk("Mailbox loaded\n"); 150 | ret = register_chrdev(MAJOR_NUM, DEVICE_NAME, &mbx_fops); 151 | if (ret != 0) 152 | return ret; 153 | 154 | /* Create a "mbx" class which will show up as /sys/class/mbx. The main 155 | benefit will be to cause udev/mdev to create the appropriate 156 | device node in/dev */ 157 | mbx_class = class_create(THIS_MODULE, DEVICE_NAME); 158 | for (i = 0; i < NUM_MAILBOXES; i++) { 159 | mailboxes[i].mbx_len = 0; 160 | init_waitqueue_head(&mailboxes[i].wq); 161 | device_create(mbx_class, NULL, 162 | MKDEV(MAJOR_NUM, i), NULL, "mbx%d", i); 163 | } 164 | 165 | return 0; 166 | } 167 | 168 | void __exit mbx_exit(void) 169 | { 170 | int i; 171 | 172 | for (i = 0; i < NUM_MAILBOXES; i++) { 173 | device_destroy(mbx_class, MKDEV(MAJOR_NUM, i)); 174 | } 175 | class_destroy(mbx_class); 176 | 177 | unregister_chrdev(MAJOR_NUM, DEVICE_NAME); 178 | printk("Mailbox unloaded\n"); 179 | } 180 | 181 | module_init(mbx_init); 182 | module_exit(mbx_exit); 183 | MODULE_LICENSE("GPL"); 184 | MODULE_AUTHOR("Chris Simmonds"); 185 | MODULE_DESCRIPTION("A sort of mailbox"); 186 | -------------------------------------------------------------------------------- /Chapter16/plot/README: -------------------------------------------------------------------------------- 1 | Notes on generating the latency diagrams 2 | ---------------------------------------- 3 | 4 | First you will need gnuplot. Everything is done at the 5 | command-line, so you can install the smaller "no X" package: 6 | 7 | $ sudo apt-get install gnuplot-nox 8 | 9 | Then, to generate the plots from the data files, run the do-plot file: 10 | 11 | $ gnuplot do-plot 12 | 13 | -------------------------------------------------------------------------------- /Chapter16/plot/bbb-yocto-nopreempt-floodping.dat: -------------------------------------------------------------------------------- 1 | # /dev/cpu_dma_latency set to 0us 2 | # Histogram 3 | 000000 000000 4 | 000001 000000 5 | 000002 000000 6 | 000003 000000 7 | 000004 000000 8 | 000005 000000 9 | 000006 000000 10 | 000007 000000 11 | 000008 000000 12 | 000009 000000 13 | 000010 000000 14 | 000011 000013 15 | 000012 000036 16 | 000013 000072 17 | 000014 001919 18 | 000015 003735 19 | 000016 016914 20 | 000017 020885 21 | 000018 006594 22 | 000019 002211 23 | 000020 002122 24 | 000021 001852 25 | 000022 001546 26 | 000023 001293 27 | 000024 001131 28 | 000025 000880 29 | 000026 000774 30 | 000027 000833 31 | 000028 000776 32 | 000029 000751 33 | 000030 000729 34 | 000031 000674 35 | 000032 000611 36 | 000033 000495 37 | 000034 000522 38 | 000035 000678 39 | 000036 000691 40 | 000037 000628 41 | 000038 000603 42 | 000039 000631 43 | 000040 000638 44 | 000041 000582 45 | 000042 000554 46 | 000043 000517 47 | 000044 000520 48 | 000045 000540 49 | 000046 000568 50 | 000047 000648 51 | 000048 000680 52 | 000049 000593 53 | 000050 000549 54 | 000051 000546 55 | 000052 000606 56 | 000053 000589 57 | 000054 000577 58 | 000055 000591 59 | 000056 000603 60 | 000057 000693 61 | 000058 000670 62 | 000059 000664 63 | 000060 000610 64 | 000061 000632 65 | 000062 000582 66 | 000063 000652 67 | 000064 000619 68 | 000065 000632 69 | 000066 000644 70 | 000067 000755 71 | 000068 000654 72 | 000069 001207 73 | 000070 002043 74 | 000071 002162 75 | 000072 001354 76 | 000073 000776 77 | 000074 000495 78 | 000075 000418 79 | 000076 000376 80 | 000077 000535 81 | 000078 000686 82 | 000079 000596 83 | 000080 000413 84 | 000081 000239 85 | 000082 000132 86 | 000083 000073 87 | 000084 000053 88 | 000085 000031 89 | 000086 000008 90 | 000087 000012 91 | 000088 000010 92 | 000089 000005 93 | 000090 000004 94 | 000091 000005 95 | 000092 000002 96 | 000093 000002 97 | 000094 000001 98 | 000095 000000 99 | 000096 000001 100 | 000097 000002 101 | 000098 000000 102 | 000099 000000 103 | 000100 000000 104 | 000101 000000 105 | 000102 000000 106 | 000103 000000 107 | 000104 000000 108 | 000105 000000 109 | 000106 000000 110 | 000107 000000 111 | 000108 000000 112 | 000109 000000 113 | 000110 000001 114 | 000111 000000 115 | 000112 000000 116 | 000113 000000 117 | 000114 000000 118 | 000115 000000 119 | 000116 000000 120 | 000117 000000 121 | 000118 000000 122 | 000119 000000 123 | 000120 000000 124 | 000121 000000 125 | 000122 000000 126 | 000123 000000 127 | 000124 000000 128 | 000125 000000 129 | 000126 000000 130 | 000127 000000 131 | 000128 000000 132 | 000129 000000 133 | 000130 000000 134 | 000131 000000 135 | 000132 000000 136 | 000133 000000 137 | 000134 000000 138 | 000135 000000 139 | 000136 000000 140 | 000137 000000 141 | 000138 000000 142 | 000139 000000 143 | 000140 000001 144 | 000141 000000 145 | 000142 000000 146 | 000143 000000 147 | 000144 000000 148 | 000145 000000 149 | 000146 000000 150 | 000147 000000 151 | 000148 000000 152 | 000149 000000 153 | 000150 000000 154 | 000151 000000 155 | 000152 000000 156 | 000153 000000 157 | 000154 000000 158 | 000155 000000 159 | 000156 000000 160 | 000157 000000 161 | 000158 000000 162 | 000159 000000 163 | 000160 000000 164 | 000161 000000 165 | 000162 000000 166 | 000163 000000 167 | 000164 000000 168 | 000165 000000 169 | 000166 000000 170 | 000167 000000 171 | 000168 000000 172 | 000169 000000 173 | 000170 000000 174 | 000171 000000 175 | 000172 000000 176 | 000173 000000 177 | 000174 000000 178 | 000175 000000 179 | 000176 000000 180 | 000177 000000 181 | 000178 000000 182 | 000179 000000 183 | 000180 000000 184 | 000181 000000 185 | 000182 000000 186 | 000183 000000 187 | 000184 000000 188 | 000185 000000 189 | 000186 000000 190 | 000187 000000 191 | 000188 000000 192 | 000189 000000 193 | 000190 000000 194 | 000191 000000 195 | 000192 000000 196 | 000193 000000 197 | 000194 000000 198 | 000195 000000 199 | 000196 000000 200 | 000197 000000 201 | 000198 000000 202 | 000199 000000 203 | 000200 000000 204 | 000201 000000 205 | 000202 000000 206 | 000203 000000 207 | 000204 000000 208 | 000205 000000 209 | 000206 000000 210 | 000207 000000 211 | 000208 000000 212 | 000209 000000 213 | 000210 000000 214 | 000211 000000 215 | 000212 000000 216 | 000213 000000 217 | 000214 000000 218 | 000215 000000 219 | 000216 000000 220 | 000217 000000 221 | 000218 000000 222 | 000219 000000 223 | 000220 000000 224 | 000221 000000 225 | 000222 000000 226 | 000223 000000 227 | 000224 000000 228 | 000225 000000 229 | 000226 000000 230 | 000227 000000 231 | 000228 000000 232 | 000229 000000 233 | 000230 000000 234 | 000231 000000 235 | 000232 000000 236 | 000233 000000 237 | 000234 000000 238 | 000235 000000 239 | 000236 000000 240 | 000237 000000 241 | 000238 000000 242 | 000239 000000 243 | 000240 000000 244 | 000241 000000 245 | 000242 000000 246 | 000243 000000 247 | 000244 000000 248 | 000245 000000 249 | 000246 000000 250 | 000247 000000 251 | 000248 000000 252 | 000249 000000 253 | 000250 000000 254 | 000251 000000 255 | 000252 000000 256 | 000253 000000 257 | 000254 000000 258 | 000255 000000 259 | 000256 000000 260 | 000257 000000 261 | 000258 000000 262 | 000259 000000 263 | 000260 000000 264 | 000261 000000 265 | 000262 000000 266 | 000263 000000 267 | 000264 000000 268 | 000265 000000 269 | 000266 000000 270 | 000267 000000 271 | 000268 000000 272 | 000269 000000 273 | 000270 000000 274 | 000271 000000 275 | 000272 000000 276 | 000273 000000 277 | 000274 000000 278 | 000275 000000 279 | 000276 000000 280 | 000277 000000 281 | 000278 000000 282 | 000279 000000 283 | 000280 000000 284 | 000281 000000 285 | 000282 000000 286 | 000283 000000 287 | 000284 000000 288 | 000285 000000 289 | 000286 000000 290 | 000287 000000 291 | 000288 000000 292 | 000289 000000 293 | 000290 000000 294 | 000291 000000 295 | 000292 000000 296 | 000293 000000 297 | 000294 000000 298 | 000295 000000 299 | 000296 000000 300 | 000297 000000 301 | 000298 000000 302 | 000299 000000 303 | 000300 000000 304 | 000301 000000 305 | 000302 000000 306 | 000303 000000 307 | 000304 000000 308 | 000305 000000 309 | 000306 000000 310 | 000307 000000 311 | 000308 000000 312 | 000309 000000 313 | 000310 000000 314 | 000311 000000 315 | 000312 000000 316 | 000313 000000 317 | 000314 000000 318 | 000315 000000 319 | 000316 000000 320 | 000317 000000 321 | 000318 000000 322 | 000319 000000 323 | 000320 000000 324 | 000321 000000 325 | 000322 000000 326 | 000323 000000 327 | 000324 000000 328 | 000325 000000 329 | 000326 000000 330 | 000327 000000 331 | 000328 000000 332 | 000329 000000 333 | 000330 000000 334 | 000331 000000 335 | 000332 000000 336 | 000333 000000 337 | 000334 000000 338 | 000335 000000 339 | 000336 000000 340 | 000337 000000 341 | 000338 000000 342 | 000339 000000 343 | 000340 000000 344 | 000341 000000 345 | 000342 000000 346 | 000343 000000 347 | 000344 000000 348 | 000345 000000 349 | 000346 000000 350 | 000347 000000 351 | 000348 000000 352 | 000349 000000 353 | 000350 000000 354 | 000351 000000 355 | 000352 000000 356 | 000353 000000 357 | 000354 000000 358 | 000355 000000 359 | 000356 000000 360 | 000357 000000 361 | 000358 000000 362 | 000359 000000 363 | 000360 000000 364 | 000361 000000 365 | 000362 000000 366 | 000363 000000 367 | 000364 000000 368 | 000365 000000 369 | 000366 000000 370 | 000367 000000 371 | 000368 000000 372 | 000369 000000 373 | 000370 000000 374 | 000371 000000 375 | 000372 000000 376 | 000373 000000 377 | 000374 000000 378 | 000375 000000 379 | 000376 000000 380 | 000377 000000 381 | 000378 000000 382 | 000379 000000 383 | 000380 000000 384 | 000381 000001 385 | 000382 000000 386 | 000383 000000 387 | 000384 000001 388 | 000385 000001 389 | 000386 000002 390 | 000387 000000 391 | 000388 000000 392 | 000389 000000 393 | 000390 000000 394 | 000391 000001 395 | 000392 000000 396 | 000393 000000 397 | 000394 000000 398 | 000395 000000 399 | 000396 000000 400 | 000397 000002 401 | 000398 000000 402 | 000399 000000 403 | 000400 000000 404 | 000401 000002 405 | 000402 000001 406 | 000403 000000 407 | 000404 000001 408 | 000405 000000 409 | 000406 000001 410 | 000407 000002 411 | 000408 000000 412 | 000409 000000 413 | 000410 000000 414 | 000411 000001 415 | 000412 000000 416 | 000413 000000 417 | 000414 000001 418 | 000415 000000 419 | 000416 000001 420 | 000417 000002 421 | 000418 000000 422 | 000419 000000 423 | 000420 000000 424 | 000421 000000 425 | 000422 000003 426 | 000423 000001 427 | 000424 000000 428 | 000425 000000 429 | 000426 000001 430 | 000427 000000 431 | 000428 000002 432 | 000429 000000 433 | 000430 000000 434 | 000431 000000 435 | 000432 000001 436 | 000433 000001 437 | 000434 000000 438 | 000435 000000 439 | 000436 000000 440 | 000437 000001 441 | 000438 000001 442 | 000439 000000 443 | 000440 000000 444 | 000441 000001 445 | 000442 000000 446 | 000443 000000 447 | 000444 000000 448 | 000445 000000 449 | 000446 000000 450 | 000447 000000 451 | 000448 000000 452 | 000449 000000 453 | 000450 000001 454 | 000451 000000 455 | 000452 000000 456 | 000453 000000 457 | 000454 000001 458 | 000455 000002 459 | 000456 000000 460 | 000457 000000 461 | 000458 000001 462 | 000459 000000 463 | 000460 000000 464 | 000461 000000 465 | 000462 000000 466 | 000463 000001 467 | 000464 000000 468 | 000465 000001 469 | 000466 000000 470 | 000467 000000 471 | 000468 000000 472 | 000469 000000 473 | 000470 000000 474 | 000471 000000 475 | 000472 000000 476 | 000473 000001 477 | 000474 000000 478 | 000475 000000 479 | 000476 000000 480 | 000477 000000 481 | 000478 000001 482 | 000479 000000 483 | 000480 000000 484 | 000481 000001 485 | 000482 000000 486 | 000483 000000 487 | 000484 000000 488 | 000485 000000 489 | 000486 000000 490 | 000487 000000 491 | 000488 000000 492 | 000489 000000 493 | 000490 000000 494 | 000491 000000 495 | 000492 000000 496 | 000493 000000 497 | 000494 000000 498 | 000495 000000 499 | 000496 000000 500 | 000497 000000 501 | 000498 000000 502 | 000499 000001 503 | # Total: 000099993 504 | # Min Latencies: 00011 505 | # Avg Latencies: 00032 506 | # Max Latencies: 00509 507 | # Histogram Overflows: 00007 508 | # Histogram Overflow at cycle number: 509 | # Thread 0: 04218 38218 46218 54218 64218 72218 98218 510 | 511 | -------------------------------------------------------------------------------- /Chapter16/plot/bbb-yocto-preempt-floodping.dat: -------------------------------------------------------------------------------- 1 | # /dev/cpu_dma_latency set to 0us 2 | # Histogram 3 | 000000 000000 4 | 000001 000000 5 | 000002 000000 6 | 000003 000000 7 | 000004 000000 8 | 000005 000000 9 | 000006 000000 10 | 000007 000000 11 | 000008 000000 12 | 000009 000000 13 | 000010 000000 14 | 000011 000000 15 | 000012 000000 16 | 000013 000002 17 | 000014 000025 18 | 000015 000040 19 | 000016 000051 20 | 000017 000499 21 | 000018 000468 22 | 000019 002752 23 | 000020 013070 24 | 000021 016483 25 | 000022 005033 26 | 000023 002282 27 | 000024 002522 28 | 000025 002188 29 | 000026 001794 30 | 000027 001431 31 | 000028 001134 32 | 000029 001069 33 | 000030 000811 34 | 000031 000734 35 | 000032 000829 36 | 000033 000845 37 | 000034 000842 38 | 000035 000719 39 | 000036 000722 40 | 000037 000718 41 | 000038 000677 42 | 000039 000593 43 | 000040 000468 44 | 000041 000576 45 | 000042 000795 46 | 000043 000802 47 | 000044 000681 48 | 000045 000673 49 | 000046 000653 50 | 000047 000705 51 | 000048 000667 52 | 000049 000577 53 | 000050 000526 54 | 000051 000548 55 | 000052 000543 56 | 000053 000466 57 | 000054 000431 58 | 000055 000433 59 | 000056 000536 60 | 000057 000632 61 | 000058 000765 62 | 000059 000845 63 | 000060 000857 64 | 000061 000664 65 | 000062 000504 66 | 000063 000509 67 | 000064 000627 68 | 000065 000750 69 | 000066 000762 70 | 000067 000723 71 | 000068 000725 72 | 000069 000643 73 | 000070 000602 74 | 000071 000643 75 | 000072 000609 76 | 000073 000679 77 | 000074 000646 78 | 000075 000620 79 | 000076 000603 80 | 000077 000557 81 | 000078 000596 82 | 000079 000627 83 | 000080 000641 84 | 000081 000615 85 | 000082 000616 86 | 000083 000879 87 | 000084 001703 88 | 000085 002465 89 | 000086 001998 90 | 000087 001203 91 | 000088 000786 92 | 000089 000646 93 | 000090 000420 94 | 000091 000241 95 | 000092 000163 96 | 000093 000284 97 | 000094 000556 98 | 000095 000708 99 | 000096 000529 100 | 000097 000356 101 | 000098 000207 102 | 000099 000141 103 | 000100 000098 104 | 000101 000075 105 | 000102 000083 106 | 000103 000097 107 | 000104 000105 108 | 000105 000110 109 | 000106 000123 110 | 000107 000090 111 | 000108 000107 112 | 000109 000107 113 | 000110 000067 114 | 000111 000050 115 | 000112 000035 116 | 000113 000035 117 | 000114 000022 118 | 000115 000015 119 | 000116 000008 120 | 000117 000005 121 | 000118 000002 122 | 000119 000005 123 | 000120 000000 124 | 000121 000002 125 | 000122 000000 126 | 000123 000000 127 | 000124 000000 128 | 000125 000000 129 | 000126 000000 130 | 000127 000000 131 | 000128 000000 132 | 000129 000000 133 | 000130 000000 134 | 000131 000000 135 | 000132 000000 136 | 000133 000000 137 | 000134 000000 138 | 000135 000000 139 | 000136 000000 140 | 000137 000000 141 | 000138 000000 142 | 000139 000000 143 | 000140 000000 144 | 000141 000000 145 | 000142 000000 146 | 000143 000000 147 | 000144 000000 148 | 000145 000000 149 | 000146 000000 150 | 000147 000000 151 | 000148 000000 152 | 000149 000000 153 | 000150 000000 154 | 000151 000000 155 | 000152 000000 156 | 000153 000000 157 | 000154 000000 158 | 000155 000000 159 | 000156 000000 160 | 000157 000000 161 | 000158 000000 162 | 000159 000000 163 | 000160 000000 164 | 000161 000000 165 | 000162 000000 166 | 000163 000000 167 | 000164 000000 168 | 000165 000000 169 | 000166 000000 170 | 000167 000000 171 | 000168 000000 172 | 000169 000000 173 | 000170 000000 174 | 000171 000000 175 | 000172 000000 176 | 000173 000000 177 | 000174 000000 178 | 000175 000000 179 | 000176 000000 180 | 000177 000000 181 | 000178 000000 182 | 000179 000000 183 | 000180 000000 184 | 000181 000000 185 | 000182 000000 186 | 000183 000000 187 | 000184 000000 188 | 000185 000000 189 | 000186 000000 190 | 000187 000000 191 | 000188 000000 192 | 000189 000000 193 | 000190 000000 194 | 000191 000000 195 | 000192 000000 196 | 000193 000000 197 | 000194 000000 198 | 000195 000000 199 | 000196 000000 200 | 000197 000000 201 | 000198 000000 202 | 000199 000000 203 | 000200 000000 204 | 000201 000000 205 | 000202 000000 206 | 000203 000000 207 | 000204 000000 208 | 000205 000000 209 | 000206 000000 210 | 000207 000000 211 | 000208 000000 212 | 000209 000000 213 | 000210 000001 214 | 000211 000000 215 | 000212 000000 216 | 000213 000000 217 | 000214 000000 218 | 000215 000000 219 | 000216 000000 220 | 000217 000000 221 | 000218 000000 222 | 000219 000000 223 | 000220 000000 224 | 000221 000000 225 | 000222 000000 226 | 000223 000000 227 | 000224 000000 228 | 000225 000000 229 | 000226 000000 230 | 000227 000000 231 | 000228 000000 232 | 000229 000000 233 | 000230 000000 234 | 000231 000000 235 | 000232 000000 236 | 000233 000000 237 | 000234 000000 238 | 000235 000000 239 | 000236 000000 240 | 000237 000000 241 | 000238 000000 242 | 000239 000000 243 | 000240 000000 244 | 000241 000000 245 | 000242 000000 246 | 000243 000000 247 | 000244 000000 248 | 000245 000000 249 | 000246 000000 250 | 000247 000000 251 | 000248 000000 252 | 000249 000000 253 | 000250 000000 254 | 000251 000000 255 | 000252 000000 256 | 000253 000000 257 | 000254 000000 258 | 000255 000000 259 | 000256 000000 260 | 000257 000000 261 | 000258 000000 262 | 000259 000000 263 | 000260 000000 264 | 000261 000000 265 | 000262 000000 266 | 000263 000000 267 | 000264 000000 268 | 000265 000000 269 | 000266 000000 270 | 000267 000000 271 | 000268 000000 272 | 000269 000000 273 | 000270 000000 274 | 000271 000000 275 | 000272 000000 276 | 000273 000000 277 | 000274 000000 278 | 000275 000000 279 | 000276 000000 280 | 000277 000000 281 | 000278 000000 282 | 000279 000000 283 | 000280 000000 284 | 000281 000000 285 | 000282 000000 286 | 000283 000000 287 | 000284 000000 288 | 000285 000000 289 | 000286 000000 290 | 000287 000000 291 | 000288 000000 292 | 000289 000000 293 | 000290 000000 294 | 000291 000000 295 | 000292 000000 296 | 000293 000000 297 | 000294 000000 298 | 000295 000000 299 | 000296 000000 300 | 000297 000000 301 | 000298 000000 302 | 000299 000000 303 | 000300 000000 304 | 000301 000000 305 | 000302 000000 306 | 000303 000000 307 | 000304 000000 308 | 000305 000000 309 | 000306 000000 310 | 000307 000000 311 | 000308 000000 312 | 000309 000000 313 | 000310 000000 314 | 000311 000000 315 | 000312 000000 316 | 000313 000000 317 | 000314 000000 318 | 000315 000000 319 | 000316 000000 320 | 000317 000000 321 | 000318 000000 322 | 000319 000000 323 | 000320 000000 324 | 000321 000000 325 | 000322 000000 326 | 000323 000000 327 | 000324 000000 328 | 000325 000000 329 | 000326 000000 330 | 000327 000000 331 | 000328 000000 332 | 000329 000000 333 | 000330 000000 334 | 000331 000000 335 | 000332 000000 336 | 000333 000000 337 | 000334 000000 338 | 000335 000000 339 | 000336 000000 340 | 000337 000000 341 | 000338 000000 342 | 000339 000000 343 | 000340 000000 344 | 000341 000000 345 | 000342 000000 346 | 000343 000000 347 | 000344 000000 348 | 000345 000000 349 | 000346 000000 350 | 000347 000000 351 | 000348 000000 352 | 000349 000000 353 | 000350 000000 354 | 000351 000000 355 | 000352 000000 356 | 000353 000000 357 | 000354 000000 358 | 000355 000000 359 | 000356 000000 360 | 000357 000000 361 | 000358 000000 362 | 000359 000000 363 | 000360 000000 364 | 000361 000000 365 | 000362 000000 366 | 000363 000000 367 | 000364 000000 368 | 000365 000000 369 | 000366 000000 370 | 000367 000000 371 | 000368 000000 372 | 000369 000000 373 | 000370 000000 374 | 000371 000000 375 | 000372 000000 376 | 000373 000000 377 | 000374 000000 378 | 000375 000000 379 | 000376 000000 380 | 000377 000000 381 | 000378 000000 382 | 000379 000000 383 | 000380 000000 384 | 000381 000000 385 | 000382 000000 386 | 000383 000000 387 | 000384 000000 388 | 000385 000000 389 | 000386 000000 390 | 000387 000000 391 | 000388 000000 392 | 000389 000000 393 | 000390 000000 394 | 000391 000000 395 | 000392 000000 396 | 000393 000000 397 | 000394 000000 398 | 000395 000000 399 | 000396 000000 400 | 000397 000000 401 | 000398 000000 402 | 000399 000000 403 | 000400 000000 404 | 000401 000000 405 | 000402 000000 406 | 000403 000000 407 | 000404 000000 408 | 000405 000000 409 | 000406 000000 410 | 000407 000000 411 | 000408 000000 412 | 000409 000000 413 | 000410 000000 414 | 000411 000000 415 | 000412 000000 416 | 000413 000000 417 | 000414 000000 418 | 000415 000000 419 | 000416 000000 420 | 000417 000000 421 | 000418 000000 422 | 000419 000000 423 | 000420 000000 424 | 000421 000000 425 | 000422 000000 426 | 000423 000000 427 | 000424 000000 428 | 000425 000000 429 | 000426 000000 430 | 000427 000000 431 | 000428 000000 432 | 000429 000000 433 | 000430 000000 434 | 000431 000000 435 | 000432 000000 436 | 000433 000000 437 | 000434 000000 438 | 000435 000000 439 | 000436 000000 440 | 000437 000000 441 | 000438 000000 442 | 000439 000000 443 | 000440 000000 444 | 000441 000000 445 | 000442 000000 446 | 000443 000000 447 | 000444 000000 448 | 000445 000000 449 | 000446 000000 450 | 000447 000000 451 | 000448 000000 452 | 000449 000000 453 | 000450 000000 454 | 000451 000000 455 | 000452 000000 456 | 000453 000000 457 | 000454 000000 458 | 000455 000000 459 | 000456 000000 460 | 000457 000000 461 | 000458 000000 462 | 000459 000000 463 | 000460 000000 464 | 000461 000000 465 | 000462 000000 466 | 000463 000000 467 | 000464 000000 468 | 000465 000000 469 | 000466 000000 470 | 000467 000000 471 | 000468 000000 472 | 000469 000000 473 | 000470 000000 474 | 000471 000000 475 | 000472 000000 476 | 000473 000000 477 | 000474 000000 478 | 000475 000000 479 | 000476 000000 480 | 000477 000000 481 | 000478 000000 482 | 000479 000000 483 | 000480 000000 484 | 000481 000000 485 | 000482 000000 486 | 000483 000000 487 | 000484 000000 488 | 000485 000000 489 | 000486 000000 490 | 000487 000000 491 | 000488 000000 492 | 000489 000000 493 | 000490 000000 494 | 000491 000000 495 | 000492 000000 496 | 000493 000000 497 | 000494 000000 498 | 000495 000000 499 | 000496 000000 500 | 000497 000000 501 | 000498 000000 502 | 000499 000000 503 | # Total: 000100000 504 | # Min Latencies: 00013 505 | # Avg Latencies: 00043 506 | # Max Latencies: 00210 507 | # Histogram Overflows: 00000 508 | # Histogram Overflow at cycle number: 509 | # Thread 0: 510 | 511 | -------------------------------------------------------------------------------- /Chapter16/plot/bbb-yocto-rt-floodping.dat: -------------------------------------------------------------------------------- 1 | # /dev/cpu_dma_latency set to 0us 2 | # Histogram 3 | 000000 000000 4 | 000001 000000 5 | 000002 000000 6 | 000003 000000 7 | 000004 000000 8 | 000005 000000 9 | 000006 000000 10 | 000007 000000 11 | 000008 000000 12 | 000009 000000 13 | 000010 000001 14 | 000011 000002 15 | 000012 000032 16 | 000013 000345 17 | 000014 004123 18 | 000015 014989 19 | 000016 016595 20 | 000017 012852 21 | 000018 006253 22 | 000019 010074 23 | 000020 013659 24 | 000021 008593 25 | 000022 003275 26 | 000023 003342 27 | 000024 003286 28 | 000025 001734 29 | 000026 000615 30 | 000027 000125 31 | 000028 000039 32 | 000029 000032 33 | 000030 000016 34 | 000031 000012 35 | 000032 000002 36 | 000033 000001 37 | 000034 000002 38 | 000035 000001 39 | 000036 000000 40 | 000037 000000 41 | 000038 000000 42 | 000039 000000 43 | 000040 000000 44 | 000041 000000 45 | 000042 000000 46 | 000043 000000 47 | 000044 000000 48 | 000045 000000 49 | 000046 000000 50 | 000047 000000 51 | 000048 000000 52 | 000049 000000 53 | 000050 000000 54 | 000051 000000 55 | 000052 000000 56 | 000053 000000 57 | 000054 000000 58 | 000055 000000 59 | 000056 000000 60 | 000057 000000 61 | 000058 000000 62 | 000059 000000 63 | 000060 000000 64 | 000061 000000 65 | 000062 000000 66 | 000063 000000 67 | 000064 000000 68 | 000065 000000 69 | 000066 000000 70 | 000067 000000 71 | 000068 000000 72 | 000069 000000 73 | 000070 000000 74 | 000071 000000 75 | 000072 000000 76 | 000073 000000 77 | 000074 000000 78 | 000075 000000 79 | 000076 000000 80 | 000077 000000 81 | 000078 000000 82 | 000079 000000 83 | 000080 000000 84 | 000081 000000 85 | 000082 000000 86 | 000083 000000 87 | 000084 000000 88 | 000085 000000 89 | 000086 000000 90 | 000087 000000 91 | 000088 000000 92 | 000089 000000 93 | 000090 000000 94 | 000091 000000 95 | 000092 000000 96 | 000093 000000 97 | 000094 000000 98 | 000095 000000 99 | 000096 000000 100 | 000097 000000 101 | 000098 000000 102 | 000099 000000 103 | 000100 000000 104 | 000101 000000 105 | 000102 000000 106 | 000103 000000 107 | 000104 000000 108 | 000105 000000 109 | 000106 000000 110 | 000107 000000 111 | 000108 000000 112 | 000109 000000 113 | 000110 000000 114 | 000111 000000 115 | 000112 000000 116 | 000113 000000 117 | 000114 000000 118 | 000115 000000 119 | 000116 000000 120 | 000117 000000 121 | 000118 000000 122 | 000119 000000 123 | 000120 000000 124 | 000121 000000 125 | 000122 000000 126 | 000123 000000 127 | 000124 000000 128 | 000125 000000 129 | 000126 000000 130 | 000127 000000 131 | 000128 000000 132 | 000129 000000 133 | 000130 000000 134 | 000131 000000 135 | 000132 000000 136 | 000133 000000 137 | 000134 000000 138 | 000135 000000 139 | 000136 000000 140 | 000137 000000 141 | 000138 000000 142 | 000139 000000 143 | 000140 000000 144 | 000141 000000 145 | 000142 000000 146 | 000143 000000 147 | 000144 000000 148 | 000145 000000 149 | 000146 000000 150 | 000147 000000 151 | 000148 000000 152 | 000149 000000 153 | 000150 000000 154 | 000151 000000 155 | 000152 000000 156 | 000153 000000 157 | 000154 000000 158 | 000155 000000 159 | 000156 000000 160 | 000157 000000 161 | 000158 000000 162 | 000159 000000 163 | 000160 000000 164 | 000161 000000 165 | 000162 000000 166 | 000163 000000 167 | 000164 000000 168 | 000165 000000 169 | 000166 000000 170 | 000167 000000 171 | 000168 000000 172 | 000169 000000 173 | 000170 000000 174 | 000171 000000 175 | 000172 000000 176 | 000173 000000 177 | 000174 000000 178 | 000175 000000 179 | 000176 000000 180 | 000177 000000 181 | 000178 000000 182 | 000179 000000 183 | 000180 000000 184 | 000181 000000 185 | 000182 000000 186 | 000183 000000 187 | 000184 000000 188 | 000185 000000 189 | 000186 000000 190 | 000187 000000 191 | 000188 000000 192 | 000189 000000 193 | 000190 000000 194 | 000191 000000 195 | 000192 000000 196 | 000193 000000 197 | 000194 000000 198 | 000195 000000 199 | 000196 000000 200 | 000197 000000 201 | 000198 000000 202 | 000199 000000 203 | 000200 000000 204 | 000201 000000 205 | 000202 000000 206 | 000203 000000 207 | 000204 000000 208 | 000205 000000 209 | 000206 000000 210 | 000207 000000 211 | 000208 000000 212 | 000209 000000 213 | 000210 000000 214 | 000211 000000 215 | 000212 000000 216 | 000213 000000 217 | 000214 000000 218 | 000215 000000 219 | 000216 000000 220 | 000217 000000 221 | 000218 000000 222 | 000219 000000 223 | 000220 000000 224 | 000221 000000 225 | 000222 000000 226 | 000223 000000 227 | 000224 000000 228 | 000225 000000 229 | 000226 000000 230 | 000227 000000 231 | 000228 000000 232 | 000229 000000 233 | 000230 000000 234 | 000231 000000 235 | 000232 000000 236 | 000233 000000 237 | 000234 000000 238 | 000235 000000 239 | 000236 000000 240 | 000237 000000 241 | 000238 000000 242 | 000239 000000 243 | 000240 000000 244 | 000241 000000 245 | 000242 000000 246 | 000243 000000 247 | 000244 000000 248 | 000245 000000 249 | 000246 000000 250 | 000247 000000 251 | 000248 000000 252 | 000249 000000 253 | 000250 000000 254 | 000251 000000 255 | 000252 000000 256 | 000253 000000 257 | 000254 000000 258 | 000255 000000 259 | 000256 000000 260 | 000257 000000 261 | 000258 000000 262 | 000259 000000 263 | 000260 000000 264 | 000261 000000 265 | 000262 000000 266 | 000263 000000 267 | 000264 000000 268 | 000265 000000 269 | 000266 000000 270 | 000267 000000 271 | 000268 000000 272 | 000269 000000 273 | 000270 000000 274 | 000271 000000 275 | 000272 000000 276 | 000273 000000 277 | 000274 000000 278 | 000275 000000 279 | 000276 000000 280 | 000277 000000 281 | 000278 000000 282 | 000279 000000 283 | 000280 000000 284 | 000281 000000 285 | 000282 000000 286 | 000283 000000 287 | 000284 000000 288 | 000285 000000 289 | 000286 000000 290 | 000287 000000 291 | 000288 000000 292 | 000289 000000 293 | 000290 000000 294 | 000291 000000 295 | 000292 000000 296 | 000293 000000 297 | 000294 000000 298 | 000295 000000 299 | 000296 000000 300 | 000297 000000 301 | 000298 000000 302 | 000299 000000 303 | 000300 000000 304 | 000301 000000 305 | 000302 000000 306 | 000303 000000 307 | 000304 000000 308 | 000305 000000 309 | 000306 000000 310 | 000307 000000 311 | 000308 000000 312 | 000309 000000 313 | 000310 000000 314 | 000311 000000 315 | 000312 000000 316 | 000313 000000 317 | 000314 000000 318 | 000315 000000 319 | 000316 000000 320 | 000317 000000 321 | 000318 000000 322 | 000319 000000 323 | 000320 000000 324 | 000321 000000 325 | 000322 000000 326 | 000323 000000 327 | 000324 000000 328 | 000325 000000 329 | 000326 000000 330 | 000327 000000 331 | 000328 000000 332 | 000329 000000 333 | 000330 000000 334 | 000331 000000 335 | 000332 000000 336 | 000333 000000 337 | 000334 000000 338 | 000335 000000 339 | 000336 000000 340 | 000337 000000 341 | 000338 000000 342 | 000339 000000 343 | 000340 000000 344 | 000341 000000 345 | 000342 000000 346 | 000343 000000 347 | 000344 000000 348 | 000345 000000 349 | 000346 000000 350 | 000347 000000 351 | 000348 000000 352 | 000349 000000 353 | 000350 000000 354 | 000351 000000 355 | 000352 000000 356 | 000353 000000 357 | 000354 000000 358 | 000355 000000 359 | 000356 000000 360 | 000357 000000 361 | 000358 000000 362 | 000359 000000 363 | 000360 000000 364 | 000361 000000 365 | 000362 000000 366 | 000363 000000 367 | 000364 000000 368 | 000365 000000 369 | 000366 000000 370 | 000367 000000 371 | 000368 000000 372 | 000369 000000 373 | 000370 000000 374 | 000371 000000 375 | 000372 000000 376 | 000373 000000 377 | 000374 000000 378 | 000375 000000 379 | 000376 000000 380 | 000377 000000 381 | 000378 000000 382 | 000379 000000 383 | 000380 000000 384 | 000381 000000 385 | 000382 000000 386 | 000383 000000 387 | 000384 000000 388 | 000385 000000 389 | 000386 000000 390 | 000387 000000 391 | 000388 000000 392 | 000389 000000 393 | 000390 000000 394 | 000391 000000 395 | 000392 000000 396 | 000393 000000 397 | 000394 000000 398 | 000395 000000 399 | 000396 000000 400 | 000397 000000 401 | 000398 000000 402 | 000399 000000 403 | 000400 000000 404 | 000401 000000 405 | 000402 000000 406 | 000403 000000 407 | 000404 000000 408 | 000405 000000 409 | 000406 000000 410 | 000407 000000 411 | 000408 000000 412 | 000409 000000 413 | 000410 000000 414 | 000411 000000 415 | 000412 000000 416 | 000413 000000 417 | 000414 000000 418 | 000415 000000 419 | 000416 000000 420 | 000417 000000 421 | 000418 000000 422 | 000419 000000 423 | 000420 000000 424 | 000421 000000 425 | 000422 000000 426 | 000423 000000 427 | 000424 000000 428 | 000425 000000 429 | 000426 000000 430 | 000427 000000 431 | 000428 000000 432 | 000429 000000 433 | 000430 000000 434 | 000431 000000 435 | 000432 000000 436 | 000433 000000 437 | 000434 000000 438 | 000435 000000 439 | 000436 000000 440 | 000437 000000 441 | 000438 000000 442 | 000439 000000 443 | 000440 000000 444 | 000441 000000 445 | 000442 000000 446 | 000443 000000 447 | 000444 000000 448 | 000445 000000 449 | 000446 000000 450 | 000447 000000 451 | 000448 000000 452 | 000449 000000 453 | 000450 000000 454 | 000451 000000 455 | 000452 000000 456 | 000453 000000 457 | 000454 000000 458 | 000455 000000 459 | 000456 000000 460 | 000457 000000 461 | 000458 000000 462 | 000459 000000 463 | 000460 000000 464 | 000461 000000 465 | 000462 000000 466 | 000463 000000 467 | 000464 000000 468 | 000465 000000 469 | 000466 000000 470 | 000467 000000 471 | 000468 000000 472 | 000469 000000 473 | 000470 000000 474 | 000471 000000 475 | 000472 000000 476 | 000473 000000 477 | 000474 000000 478 | 000475 000000 479 | 000476 000000 480 | 000477 000000 481 | 000478 000000 482 | 000479 000000 483 | 000480 000000 484 | 000481 000000 485 | 000482 000000 486 | 000483 000000 487 | 000484 000000 488 | 000485 000000 489 | 000486 000000 490 | 000487 000000 491 | 000488 000000 492 | 000489 000000 493 | 000490 000000 494 | 000491 000000 495 | 000492 000000 496 | 000493 000000 497 | 000494 000000 498 | 000495 000000 499 | 000496 000000 500 | 000497 000000 501 | 000498 000000 502 | 000499 000000 503 | # Total: 000100000 504 | # Min Latencies: 00010 505 | # Avg Latencies: 00018 506 | # Max Latencies: 00035 507 | # Histogram Overflows: 00000 508 | # Histogram Overflow at cycle number: 509 | # Thread 0: 510 | 511 | -------------------------------------------------------------------------------- /Chapter16/plot/do-plot: -------------------------------------------------------------------------------- 1 | # load "do-plot" 2 | set term png size 800,600 3 | set output "test1.png" 4 | set logscale y 5 | set xlabel "microseconds" 6 | set ylabel "samples" 7 | set title "No preempt" 8 | plot "bbb-yocto-nopreempt-floodping.dat" with filledcurves x1 9 | set output "test2.png" 10 | set title "Preempt" 11 | plot "bbb-yocto-preempt-floodping.dat" with filledcurves x1 12 | set output "test3.png" 13 | set title "RT" 14 | plot "bbb-yocto-rt-floodping.dat" with filledcurves x1 15 | 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## $5 Tech Unlocked 2021! 2 | [Buy and download this product for only $5 on PacktPub.com](https://www.packtpub.com/) 3 | ----- 4 | *The $5 campaign runs from __December 15th 2020__ to __January 13th 2021.__* 5 | 6 | # Mastering Embedded Linux Programming – Second Edition 7 | 8 | This is the code repository for [Mastering Embedded Linux Programming - Second Edition](https://www.packtpub.com/networking-and-servers/mastering-embedded-linux-programming-second-edition?utm_source=github&utm_medium=repository&utm_campaign=9781787283282), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish. 9 | 10 | ## About the Book 11 | Embedded Linux is widely used and there’s a need of selection, organization, and presentation of embedded linux. 12 | 13 | Mastering Embedded Linux Programming 2nd edition takes you through the product cycle and gives you an in-depth description of the components and options that are available at each stage.The aim of this book is to help you create efficient and secure embedded devices using Linux. You will begin by learning about tool chains, boot loaders, the Linux kernel, and how to configure a root file system to create a basic working device which will be followed by using Buildroot and Yocto to speed up and simplify the development process .Key topics include basic system set-up, toolchains, accessing hardware at a low-level, robustness, real-time behavior and security.Its purpose is to make you aware how to construct an embedded Linux using open source projects to produce a robust and reliable system by understanding about Linux 4.9 Yocto’s Pyro 2.3 along with the latest Buildroot. 14 | 15 | By the end of the book , you will be able to derive a wide choice of solutions to solve a particular problem. 16 | 17 | ## Instructions and Navigation 18 | 19 | All of the code is organized into folders. For example, Chapter04. 20 | 21 | 22 | The code will look like the following: 23 | ``` 24 | /dts-v1/; 25 | /{ 26 | model = "TI AM335x BeagleBone"; 27 | compatible = "ti,am33xx"; 28 | #address-cells = <1>; 29 | #size-cells = <1>; 30 | cpus { 31 | #address-cells = <1>; 32 | #size-cells = <0>; 33 | cpu@0 { 34 | compatible = "arm,cortex-a8"; 35 | device_type = "cpu"; 36 | reg = <0>; 37 | }; 38 | }; 39 | memory@0x80000000 { 40 | device_type = "memory"; 41 | reg = <0x80000000 0x20000000>; /* 512 MB */ 42 | }; 43 | }; 44 | ``` 45 | 46 | At the end of the ROM code phase, the next stage bootloader is present in on-chip memory and the ROM code jumps to the beginning of that code. 47 | 48 | ## Errata 49 | 50 | (Page 136) If you get errors after executing the commands mentioned in the book. Please click the below link to find the solution to get rid of those errors: 51 | https://unix.stackexchange.com/questions/579640/u-boot-wrong-ramdisk-image-format-with-initramfs-on-beaglebone-black 52 | 53 | 54 | ## Related Embedded Linux Programming Products 55 | 56 | * [GNU/Linux Rapid Embedded Programming](https://www.packtpub.com/hardware-and-creative/gnulinux-rapid-embedded-programming?utm_source=github&utm_medium=repository&utm_campaign=9781786461803) 57 | 58 | * [Mastering Kali Linux for Advanced Penetration Testing - Second Edition](https://www.packtpub.com/networking-and-servers/mastering-kali-linux-advanced-penetration-testing-second-edition?utm_source=github&utm_medium=repository&utm_campaign=9781787120235) 59 | 60 | * [Mastering Linux Kernel Development](https://www.packtpub.com/application-development/mastering-linux-kernel-development?utm_source=github&utm_medium=repository&utm_campaign=9781785883057) 61 | 62 | -------------------------------------------------------------------------------- /copy-yoctoproject-image-to-sdcard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -ne 2 ]; then 4 | echo "Usage: $0 [machine] [image]" 5 | echo " machine is, e.g., beaglebone" 6 | echo " image is, e.g., core-image-minimal" 7 | exit 1 8 | fi 9 | 10 | if [ -z BUILDDIR ]; then 11 | echo "Please source oe-init-build-env" 12 | exit 1 13 | fi 14 | 15 | BOOT_PART=/media/${USER}/boot 16 | ROOTFS_PART=/media/${USER}/rootfs 17 | 18 | MACHINE=$1 19 | IMAGE=$2-${MACHINE} 20 | 21 | IMAGES_DIR=tmp/deploy/images/${MACHINE} 22 | 23 | if [ ! -d $BOOT_PART ]; then 24 | echo "Can't find $BOOT_PART on sdcard" 25 | exit 1 26 | fi 27 | 28 | if [ ! -d $ROOTFS_PART ]; then 29 | echo "Can't find $ROOTFS_PART on sdcard" 30 | exit 1 31 | fi 32 | 33 | cp ${IMAGES_DIR}/MLO ${BOOT_PART} 34 | if [ $? -ne 0 ]; then echo "Error: dd"; exit 1; fi 35 | cp ${IMAGES_DIR}/u-boot.img ${BOOT_PART} 36 | if [ $? -ne 0 ]; then echo "Error: dd"; exit 1; fi 37 | 38 | sudo tar -C $ROOTFS_PART -xf ${IMAGES_DIR}/${IMAGE}.tar.bz2 39 | if [ $? -ne 0 ]; then echo "Error: dd"; exit 1; fi 40 | 41 | echo "Success!" 42 | -------------------------------------------------------------------------------- /format-sdcard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Format a microSD card for the BeagelBone Black 3 | # Mastering Mebedded Linux Programming 4 | # Copyright (c) Chris Simmonds, 2017 5 | 6 | if [ $# -ne 1 ]; then 7 | echo "Usage: $0 [drive]" 8 | echo " drive is 'sdb', 'mmcblk0', etc" 9 | exit 1 10 | fi 11 | 12 | function version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; } 13 | 14 | DRIVE=$1 15 | 16 | # Check the drive exists in /sys/block 17 | if [ ! -e /sys/block/${DRIVE}/size ]; then 18 | echo "Drive does not exist" 19 | exit 1 20 | fi 21 | 22 | # Check it is a flash drive (size < 32GiB) 23 | NUM_SECTORS=`cat /sys/block/${DRIVE}/size` 24 | if [ $NUM_SECTORS -eq 0 -o $NUM_SECTORS -gt 64000000 ]; then 25 | echo "/dev/$DRIVE does not look like an SD card, bailing out" 26 | exit 1 27 | fi 28 | 29 | # Unmount any partitions that have been automounted 30 | if [ $DRIVE == "mmcblk0" ]; then 31 | sudo umount /dev/${DRIVE}* 32 | BOOT_PART=/dev/${DRIVE}p1 33 | ROOT_PART=/dev/${DRIVE}p2 34 | else 35 | sudo umount /dev/${DRIVE}[1-9] 36 | BOOT_PART=/dev/${DRIVE}1 37 | ROOT_PART=/dev/${DRIVE}2 38 | fi 39 | 40 | # Overwite any existing partiton table with zeros 41 | sudo dd if=/dev/zero of=/dev/${DRIVE} bs=1M count=10 42 | if [ $? -ne 0 ]; then echo "Error: dd"; exit 1; fi 43 | 44 | # Create 2 primary partitons on the sd card 45 | # 1: FAT32, 64 MiB, boot flag 46 | # 2: Linux, 1024 MiB 47 | # Note that the parameters to sfdisk changed slightly v2.26 48 | SFDISK_VERSION=`sfdisk --version | awk '{print $4}'` 49 | if version_gt $SFDISK_VERSION "2.26"; then 50 | sudo sfdisk /dev/${DRIVE} << EOF 51 | ,64M,0x0c,* 52 | ,1024M,L, 53 | EOF 54 | else 55 | sudo sfdisk --unit M /dev/${DRIVE} << EOF 56 | ,64,0x0c,* 57 | ,1024,L, 58 | EOF 59 | fi 60 | if [ $? -ne 0 ]; then echo "Error: sdfisk"; exit 1; fi 61 | 62 | # Format p1 with FAT32 and p2 with ext4 63 | sudo mkfs.vfat -F 16 -n boot ${BOOT_PART} 64 | if [ $? -ne 0 ]; then echo "Error: mkfs.vfat"; exit 1; fi 65 | sudo mkfs.ext4 -L rootfs ${ROOT_PART} 66 | if [ $? -ne 0 ]; then echo "Error: mkfs.ext4"; exit 1; fi 67 | 68 | echo "SUCCESS! Your microSD card has been formatted" 69 | exit 0 70 | -------------------------------------------------------------------------------- /list-libs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # List shared libraries that a program is linked to 3 | # Chris Simmonds, chris@2net.co.uk 4 | 5 | if [ $# != 1 ]; then 6 | echo "Usage: $0 [progam file]" 7 | exit 1 8 | fi 9 | ${CROSS_COMPILE}readelf -a $1 | grep "program interpreter" 10 | ${CROSS_COMPILE}readelf -a $1 | grep "Shared library" 11 | exit 0 12 | --------------------------------------------------------------------------------