Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
FlapYoJacks
Feb 12, 2009
I have been meaning to write a embedded Linux op for quite some time, but I have been too lazy or just plain forgot, but no more!

My background
I started out messing around with Linux 16 years ago with Slackware 7.1, and used it as my primary operating system ever since.
In 2010 I was unemployed and fixing cars in my garage while going to college when I was called up randomly by a friend I hadn't seen in a few years. His boss who ran a tiny engineering company (2 employees and himself) had just picked up/inherited a camera project. This particular camera ran embedded Linux off of a TI DM368 processor and they needed help getting Linux up and running on it, and I was the only "Linux guy" he knew. I was told I was only going to be needed for a few weeks. That job lasted 4 and a half years.

In those 4 and a half years I learned how to program starting with C, how to write kernel drivers, board layout, the basics of electronics, power management, project management, system architecting, and so on; basically how a product goes from concept to the shelf. During my tenure at that company I completed 3 finished projects including a Android tablet before our main client hosed over my boss and tanked his little engineering company.

6 Months later I moved halfway across the United States to Michigan to continue my career. My current project is working on a SIP phone, with my main focus on creating a incredibly flexible embedded distribution based off of buildroot with a huge focus on security.

Linux Vs RtOS
There are several reasons one should choose embedded Linux over a RtOS.

- The Linux Kernel:
The Linux kernel provides a incredibly rich feature set that gives the developer a absolutely enormous amount of support for tons of common hardware components and features, including a FULLY FEATURES AND STABLE NETWORK STACK.

- A ever growing amount of development boards.
Wand ultra cheap? Raspberry Pi being the most popular
Need Emmc? Beagle Bone black is for you!
Like Freescale (now nxp?) I like the wandboard, Boundarydevices is also great

- Feature rich SDK's
The three major ones I know of are:
Buildroot
Yocto
Ptxdist

I am a contributor to buildroot, and I am familiar as well with ptxdist. I need to someday learn yocto.


- Major distributions work on many embedded platforms as well!
Ubuntu, fedora, Gentoo, Arch, CentOS/RHEL and many more all have builds that work on many popular embedded devices.


Why does this thread exist?
I think this thread could be useful for many people getting started or even asking more advanced questions about the embedded Linux world. I will try to post any neat stuff I am doing that isn't covered under my NDA as well.

Feel free to tell me I missed something/ask me questions!

Adbot
ADBOT LOVES YOU

FlapYoJacks
Feb 12, 2009
Currently I am working on making our embedded product secure. Here are some steps I am taking to do so:

System:

SELinux: Set to enforcing.
Custom SELinux contexts for our program.
A custom kernel HAL layer for talking to the hardware.
A user space application to talk to the HAL layer.
A OTP key in the processor die that our software authenticates against, if it doesn't find it then the software won't work.
All flashing is done in house.
Root is disabled.

Web interface:
We are using nginx with the nasxi module, php7, and fcgi, all with appropriate custom SELinux contexts.
The user password is set to the company name, but the software will require the user to change the password before the product works.
Of course all passwords are hashed and salted via bcrypt (is there something better?).

Unfortunately many of our customers still want telnet, so I have to include it, but it's turned off by default and a gigantic warning will pop up on the screen telling end users that the trafic isn't encrypted and that we strongly advise people to use ssh instead.

Anything else I am missing or could do better?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
whats your threat model

no threat model = defending against nothing


ratbert90 posted:

Currently I am working on making our embedded product secure. Here are some steps I am taking to do so:

System:

SELinux: Set to enforcing.
Custom SELinux contexts for our program.
A custom kernel HAL layer for talking to the hardware.
A user space application to talk to the HAL layer.
A OTP key in the processor die that our software authenticates against, if it doesn't find it then the software won't work.
All flashing is done in house.
Root is disabled.

Web interface:
We are using nginx with the nasxi module, php7, and fcgi, all with appropriate custom SELinux contexts.
The user password is set to the company name, but the software will require the user to change the password before the product works.
Of course all passwords are hashed and salted via bcrypt (is there something better?).

Unfortunately many of our customers still want telnet, so I have to include it, but it's turned off by default and a gigantic warning will pop up on the screen telling end users that the trafic isn't encrypted and that we strongly advise people to use ssh instead.

Anything else I am missing or could do better?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

ratbert90 posted:

I have been meaning to write a embedded Linux op for quite some time, but I have been too lazy or just plain forgot, but no more!

My background
I started out messing around with Linux 16 years ago with Slackware 7.1, and used it as my primary operating system ever since.
In 2010 I was unemployed and fixing cars in my garage while going to college when I was called up randomly by a friend I hadn't seen in a few years. His boss who ran a tiny engineering company (2 employees and himself) had just picked up/inherited a camera project. This particular camera ran embedded Linux off of a TI DM368 processor and they needed help getting Linux up and running on it, and I was the only "Linux guy" he knew. I was told I was only going to be needed for a few weeks. That job lasted 4 and a half years.

In those 4 and a half years I learned how to program starting with C, how to write kernel drivers, board layout, the basics of electronics, power management, project management, system architecting, and so on; basically how a product goes from concept to the shelf. During my tenure at that company I completed 3 finished projects including a Android tablet before our main client hosed over my boss and tanked his little engineering company.

6 Months later I moved halfway across the United States to Michigan to continue my career. My current project is working on a SIP phone, with my main focus on creating a incredibly flexible embedded distribution based off of buildroot with a huge focus on security.

Linux Vs RtOS
There are several reasons one should choose embedded Linux over a RtOS.

- The Linux Kernel:
The Linux kernel provides a incredibly rich feature set that gives the developer a absolutely enormous amount of support for tons of common hardware components and features, including a FULLY FEATURES AND STABLE NETWORK STACK.

- A ever growing amount of development boards.
Wand ultra cheap? Raspberry Pi being the most popular
Need Emmc? Beagle Bone black is for you!
Like Freescale (now nxp?) I like the wandboard, Boundarydevices is also great

- Feature rich SDK's
The three major ones I know of are:
Buildroot
Yocto
Ptxdist

I am a contributor to buildroot, and I am familiar as well with ptxdist. I need to someday learn yocto.


- Major distributions work on many embedded platforms as well!
Ubuntu, fedora, Gentoo, Arch, CentOS/RHEL and many more all have builds that work on many popular embedded devices.


Why does this thread exist?
I think this thread could be useful for many people getting started or even asking more advanced questions about the embedded Linux world. I will try to post any neat stuff I am doing that isn't covered under my NDA as well.

Feel free to tell me I missed something/ask me questions!

in actual questions, i wanna modulate an ASK 433mhz thing with pretty precise microsecond timing. does linux have a "treat this thread as real-time" like windows

yippee cahier
Mar 28, 2005

I'm getting started, coming from an RTOS-on-microcontroller environment. I got myself a Raspberry Pi. Would a good starting path be to read up on and use buildroot, then attempt to write a kernel driver for some random SPI chip with interrupts?

I'm guessing a standard-ish project exposes the hardware to userspace in this way, then the actual application logic could be done in any old scripting language?

Just wanna learn some stuff here, feeling uneasy about getting pigeon-holed in RTOS land, especially when I'm reimplementing a wheel for months on end.

FlapYoJacks
Feb 12, 2009

Malcolm XML posted:

whats your threat model

no threat model = defending against nothing

My threat model isn't necessary customers, more corporate espionage than anything else. People DO and WILL pay engineers to reverse engineer this things.


Malcolm XML posted:

in actual questions, i wanna modulate an ASK 433mhz thing with pretty precise microsecond timing. does linux have a "treat this thread as real-time" like windows

http://www.embedded.com/design/operating-systems/4371651/Comparing-the-real-time-scheduling-policies-of-the-Linux-kernel-and-an-RTOS-

Round robin is what your RTOS is *probably* using.

FlapYoJacks
Feb 12, 2009

yippee cahier posted:

I'm getting started, coming from an RTOS-on-microcontroller environment. I got myself a Raspberry Pi. Would a good starting path be to read up on and use buildroot, then attempt to write a kernel driver for some random SPI chip with interrupts?

I'm guessing a standard-ish project exposes the hardware to userspace in this way, then the actual application logic could be done in any old scripting language?

Just wanna learn some stuff here, feeling uneasy about getting pigeon-holed in RTOS land, especially when I'm reimplementing a wheel for months on end.

good for you! As for buildroot? https://buildroot.org/downloads/manual/manual.html

But the gist of it is:

download buildroot
make raspberrypi_defconfig
make

Then flash the output in "output/images" to a SD card and boot.

As for you wanting to access a driver via userspace? Depends on what your driver DOES.

The common way for a new guy to do so is via a gpio call in /sys/class/gpio
http://elinux.org/CI20_GPIO_LED_Blink_Tutorial

The second way is to create a /sys/ device and shove folders and files in there, although for a simple device setup I wouldn't do that.

Another way is to create a /dev/ device and talk to it that way.

travelling wave
Nov 25, 2013

ratbert90 posted:

My threat model isn't necessary customers, more corporate espionage than anything else. People DO and WILL pay engineers to reverse engineer this things.


http://www.embedded.com/design/operating-systems/4371651/Comparing-the-real-time-scheduling-policies-of-the-Linux-kernel-and-an-RTOS-

Round robin is what your RTOS is *probably* using.

Since that article was published Linux has picked up a deadline scheduler which is designed with hard real time tasks in mind and offers better guarantees. The appendices in the link show how to use it.

ratbert90 posted:

good for you! As for buildroot? https://buildroot.org/downloads/manual/manual.html

But the gist of it is:

download buildroot
make raspberrypi_defconfig
make

This is good advice. The best way to approach buildroot is to tinker with an existing defconfig and check the the manual when you have a "how do I do X" question. The hardest thing I've found is figuring out how to build packaged with hand rolled makefiles. Most of them don't really think about cross compiling and do things like redefining CC internally and not using pkg-config properly (or at all).

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

ratbert90 posted:

My threat model isn't necessary customers, more corporate espionage than anything else. People DO and WILL pay engineers to reverse engineer this things.


http://www.embedded.com/design/operating-systems/4371651/Comparing-the-real-time-scheduling-policies-of-the-Linux-kernel-and-an-RTOS-

Round robin is what your RTOS is *probably* using.

OK re security, so your model is corp espionage. What modes of attack are you looking at? Full device access? I mean that's essentially impossible to deal with unless youre gonna go real deep and blow fuses and stuff, have designed ur board to avoid leaking info in side channel attacks like differential power analysis, thermal analysis, decapping etc. If it's just SW access, then yeah u need to limit any access that's not needed by the software to the bare minimum, disable all unnecessary services, ensure authentication by all accesses, etc


OK so for the process i can just pin it to a core and set the scheduler policy so that that process is the only thing on the core. Works for me!

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

ratbert90 posted:

good for you! As for buildroot? https://buildroot.org/downloads/manual/manual.html

But the gist of it is:

download buildroot
make raspberrypi_defconfig
make

Then flash the output in "output/images" to a SD card and boot.

As for you wanting to access a driver via userspace? Depends on what your driver DOES.

The common way for a new guy to do so is via a gpio call in /sys/class/gpio
http://elinux.org/CI20_GPIO_LED_Blink_Tutorial

The second way is to create a /sys/ device and shove folders and files in there, although for a simple device setup I wouldn't do that.

Another way is to create a /dev/ device and talk to it that way.

linux has a SPI driver and it's a device tree overlay away in raspbian, so no dicking with kernel drivers (u dont want to, its a PITA)

http://www.haifux.org/lectures/258/gpio_spi_i2c_userspace.pdf

FlapYoJacks
Feb 12, 2009

Malcolm XML posted:

OK re security, so your model is corp espionage. What modes of attack are you looking at? Full device access? I mean that's essentially impossible to deal with unless youre gonna go real deep and blow fuses and stuff, have designed ur board to avoid leaking info in side channel attacks like differential power analysis, thermal analysis, decapping etc. If it's just SW access, then yeah u need to limit any access that's not needed by the software to the bare minimum, disable all unnecessary services, ensure authentication by all accesses, etc


OK so for the process i can just pin it to a core and set the scheduler policy so that that process is the only thing on the core. Works for me!

I'm glad you asked!

We have taken device access in consideration and have implemented a OTP key into the die of the processor which our software authenticates with. If it doesn't find that key the software itself refuses to run. The FS itself is R/O and encrypted as well. As for power analyses, not much I can do there.


Malcolm XML posted:

linux has a SPI driver and it's a device tree overlay away in raspbian, so no dicking with kernel drivers (u dont want to, its a PITA)

http://www.haifux.org/lectures/258/gpio_spi_i2c_userspace.pdf


GPIO also has a standard sysfs overlay you can tinker with.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

ratbert90 posted:

I'm glad you asked!

We have taken device access in consideration and have implemented a OTP key into the die of the processor which our software authenticates with. If it doesn't find that key the software itself refuses to run. The FS itself is R/O and encrypted as well. As for power analyses, not much I can do there.



GPIO also has a standard sysfs overlay you can tinker with.

cool, but like, what kind of adversary we talking about, it's not exactly unknown to literally acid etch off encapsulation and count 1's and 0's in ROM (http://zacsblog.aperturelabs.com/2013/02/decapping-integrated-circuits-using.html)

i once knew a guy who did SEM/TEM scans of HDDs for forensics, and u can do similar poo poo on NAND: http://proceedings.spiedigitallibrary.org/proceeding.aspx?articleid=1555687

might wanna ask here for SW help beyond the standard principle of least privilege: http://forums.somethingawful.com/showthread.php?noseen=0&threadid=3500975&perpage=40&pagenumber=42#pti15

FlapYoJacks
Feb 12, 2009

Malcolm XML posted:

cool, but like, what kind of adversary we talking about, it's not exactly unknown to literally acid etch off encapsulation and count 1's and 0's in ROM (http://zacsblog.aperturelabs.com/2013/02/decapping-integrated-circuits-using.html)

i once knew a guy who did SEM/TEM scans of HDDs for forensics, and u can do similar poo poo on NAND: http://proceedings.spiedigitallibrary.org/proceeding.aspx?articleid=1555687

might wanna ask here for SW help beyond the standard principle of least privilege: http://forums.somethingawful.com/showthread.php?noseen=0&threadid=3500975&perpage=40&pagenumber=42#pti15

Telecom companies. The company I work for has 36 employees right now so we can't get too crazy. Our adversaries are multi billion dollar corporations though.

FlapYoJacks
Feb 12, 2009
forgot to say! We got Alpha boards in on Tuesday! My former boss who I got a contract gig at my current place of work doing board layout got the Alpha boards last week, and verified all the power supplies before shipping them to us.

9 bodges total for a 1300+ piece board with 17 connectors isn't too bad!

Things done so far:

- Verified USB (used for debugging, will be removed for production)

- Verified EMMC

- Verified UART 1


Linux won't be booting on this thing until late next week at the earliest. For now it's just uboot.

yippee cahier
Mar 28, 2005

Malcolm XML posted:

linux has a SPI driver and it's a device tree overlay away in raspbian, so no dicking with kernel drivers (u dont want to, its a PITA)

http://www.haifux.org/lectures/258/gpio_spi_i2c_userspace.pdf

i had find some time to get vagrant because i'm on a mac, but now make's taking care of business on my stock raspberry pi image...

i'm confident that i can make a test program go out and talk to a SPI device and will do that before diving in further. i mentioned kernel drivers because i'm trying to give myself a crash course in the field. i've written microcontroller drivers for SPI chips that require rapidly servicing interrupts, e.g. relatively decent ADCs for an application that requires samples not be dropped. i was planning on going through the linux device drivers book to try to recreate something like that in this environment. i know it's not an RTOS, but i imagine my raspberry pi doing nothing else is up to the task and this sort of thing is all in a day's work for an embedded linux dev. sound feasible?

would this be the sort of task an intermediate level developer would be expected to be doing? what else should i make sure i get familiar with?

FlapYoJacks
Feb 12, 2009
So quick update on my companies project.

I have a Micrel KSZ8794CNX connected via RGMII to a imx6 solo.

All the data lines look good, all the clock lines look good, everything looks good.

RX works, TX doesn't. What the gently caress Micrel?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

yippee cahier posted:

i had find some time to get vagrant because i'm on a mac, but now make's taking care of business on my stock raspberry pi image...

i'm confident that i can make a test program go out and talk to a SPI device and will do that before diving in further. i mentioned kernel drivers because i'm trying to give myself a crash course in the field. i've written microcontroller drivers for SPI chips that require rapidly servicing interrupts, e.g. relatively decent ADCs for an application that requires samples not be dropped. i was planning on going through the linux device drivers book to try to recreate something like that in this environment. i know it's not an RTOS, but i imagine my raspberry pi doing nothing else is up to the task and this sort of thing is all in a day's work for an embedded linux dev. sound feasible?

would this be the sort of task an intermediate level developer would be expected to be doing? what else should i make sure i get familiar with?

Here's the spi driver for the bcm chip in the rpi: http://lxr.free-electrons.com/source/drivers/spi/spi-bcm2835.c


bcm2835 lib will give you the constants for enabling DMA access to the HW, but only as root to get direct access to the MMIO registers via /dev/mem

It's pretty mechanical and not that interesting tbh

Malcolm XML fucked around with this message at 00:59 on Sep 24, 2016

Minus Pants
Jul 18, 2004
How'd you get into/learn board layout? I've had some simple low freq boards made, but I haven't found many good, practical resources for common high-speed signal routing (USB, SATA, memory, etc.). Also, what's your verification workflow like (test gear, software, lessons learned)?

FlapYoJacks
Feb 12, 2009

Minus Pants posted:

How'd you get into/learn board layout? I've had some simple low freq boards made, but I haven't found many good, practical resources for common high-speed signal routing (USB, SATA, memory, etc.). Also, what's your verification workflow like (test gear, software, lessons learned)?

I learned from my former boss who has over 30 years of experience in low level programming and board layout/electronics. He's probably the best analog guy in the United States. I suggest getting as lucky as me. :v:

yippee cahier
Mar 28, 2005

Malcolm XML posted:

Here's the spi driver for the bcm chip in the rpi: http://lxr.free-electrons.com/source/drivers/spi/spi-bcm2835.c

bcm2835 lib will give you the constants for enabling DMA access to the HW, but only as root to get direct access to the MMIO registers via /dev/mem

It's pretty mechanical and not that interesting tbh

Thanks, but I should have been more clear... eventually I intend to write a driver for a SPI connected ADC (or something similar) that uses GPIO interrupts to read out samples.

I got my stock image for my RPi booting. Is there much support for aarch64? I see changing the architecture in buildroot (and yes, running make distclean first) doesn't immediately work. Would trying to get this going be a good learning exercise for the ins and outs of buildroot?

feedmegin
Jul 30, 2008

yippee cahier posted:

Thanks, but I should have been more clear... eventually I intend to write a driver for a SPI connected ADC (or something similar) that uses GPIO interrupts to read out samples.

I got my stock image for my RPi booting. Is there much support for aarch64? I see changing the architecture in buildroot (and yes, running make distclean first) doesn't immediately work. Would trying to get this going be a good learning exercise for the ins and outs of buildroot?

My understanding is that there isn't, and it's tough to change because of reasons? Something to do with the GPU. There's a reason raspbian etc are still 32 bit. It's probably? not as simple as just switching an architecture flag.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
conveniently someone's done the hard work: http://lkml.iu.edu/hypermail/linux/kernel/1608.0/00558.html

Popete
Oct 6, 2009

This will make sure you don't suggest to the KDz
That he should grow greens instead of crushing on MCs

Grimey Drawer
This isn't strictly embedded Linux but it's an embedded project so I'll try here anyways. I have a user-land application that I want to block on a sysfs file that only returns when data (any data) is written to that file. This will signal that the user application can continue on it's way. I'm not sure how to do this easily. I created a sysfs attribute in my kernel driver and tried calling sysfs_notify() in the "store" routine of my attribute which should signal to the poll() routine my user application is blocking on, but poll always returns instantly with the event POLLIN as the return event. I tried switching the poll event to POLLPRI and it does block but never returns even after hitting sysfs_notify in the kernel "store" routine. I can see with mesgd that both my "show" and "store" routines of the kernel attribute are being hit by my user-land application. Any thoughts what I might be doing wrong? I'm also open to trying a different method than poll, I don't actually care about the data being written to the sysfs file I just need to use it as a signal to my application.

Popete
Oct 6, 2009

This will make sure you don't suggest to the KDz
That he should grow greens instead of crushing on MCs

Grimey Drawer

Minus Pants posted:

How'd you get into/learn board layout? I've had some simple low freq boards made, but I haven't found many good, practical resources for common high-speed signal routing (USB, SATA, memory, etc.). Also, what's your verification workflow like (test gear, software, lessons learned)?

As someone who dabbles in board layout but is primarily a firmware guy. Take a look at datasheets for the ICs you plant to use, they usually have a reference layout section that is very useful. Also find a board online that is doing something similiar to what you want to do and look up it's schematic. Something like laying out DDR lines is obviously a lot more sensitive but there are guidelines out there.

My main problem is that even when I have an example schematic I want to use that tells me capacitor/inductor/resistor values for a part I don't know what type to use. For example how do I decide to use ceramic/tantalum/film?

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Popete posted:

My main problem is that even when I have an example schematic I want to use that tells me capacitor/inductor/resistor values for a part I don't know what type to use. For example how do I decide to use ceramic/tantalum/film?

Ceramic is the default, cheap and really low series resistance. Occasionally there are situations where near-zero series resistance is bad (some linear regulators, for example), but typically these work good for most things that are not high voltage or very high capacitance.

Tantalum capacitors are made from tantalum, a conflict mineral (think blood diamonds, but it's blood tantalum), so avoid if possible, but they have pretty good capacitance/size/price characteristics. Used to be used more than they are now thanks to better ceramic caps and campaigns against conflict minerals. They break-down easily if voltage gets too high, so make sure you spec them with a good amount of headroom.

Electrolytic is for when you need a lot of capacitance. Generally worse in other metrics. You find these in power supplies, or as the 'bulk storage' caps.

There are a bunch of different types of film caps, depending on what they are made of. Some are low-noise and some are for high-power and high-voltage situations.

If you are doing digital electronic design, you will likely use a zillion ceramic caps, an occasional electrolytic when you need the density, and the other types for special occasions.

dougdrums
Feb 25, 2005
CLIENT REQUESTED ELECTRONIC FUNDING RECEIPT (FUNDS NOW)
I've gotten a lot of mileage out of manufacturers tech publications. TI, Atmel, Microchip, etc. have a lot of generic "how to design a device to do x" reference design papers that are really useful. Furthermore, if you don't know how to lay out a certain device, the manufacturer is usually more than eager to offer advice over email. Finally, your board shop probably has tons of experience testing all sorts of designs. When in doubt, ask! Many places are proud enough to just dump everything they know on ya! Otherwise I look at other boards and try to figure out why the designer choose to do what he or she did.

I think in most cases up to 1mm of slew (difference in trace length) is allowed for USB data. For high frequency signals, you just need to make sure that the impedance of the traces are matched, that it is shielded somewhat, and that if it's a differential signal, that the signal arrives at the same time (i.e. the traces are nearly the same length).

Trace width and spacing is generally determined by the current needed and the voltage applied, respectively.

I don't really have any formal training either so any corrections are welcome.

Here is some USB reference stuff: http://www.usb.org/developers/docs/hs_usb_pdg_r1_0.pdf

dougdrums fucked around with this message at 19:38 on Oct 3, 2016

FlapYoJacks
Feb 12, 2009
sound_soc_read doesn't read from the sound codec as expected! :argh:

Storysmith
Dec 31, 2006

ratbert90 posted:

sound_soc_read doesn't read from the sound codec as expected! :argh:

I saw your post and I'm genuinely curious now, as someone with vague interest in i2s codecs for dumb nerd poo poo: what machinations do you have to do to actually read the i2c status back? What possible reason is there to have this implemented this way? Did someone miss a volatile somewhere or something, or is this a straight up intentional behavior within the driver?

FlapYoJacks
Feb 12, 2009

Storysmith posted:

I saw your post and I'm genuinely curious now, as someone with vague interest in i2s codecs for dumb nerd poo poo: what machinations do you have to do to actually read the i2c status back? What possible reason is there to have this implemented this way? Did someone miss a volatile somewhere or something, or is this a straight up intentional behavior within the driver?

Sorry for the single line rant. I will cross post my much larger rant from the coding horrors thread here:


Let me take you down a magical journey!

Here's the C file for anybody who want's to play along:
http://lxr.free-electrons.com/source/sound/soc/codecs/tas2552.c


On line 41 you have struct reg_default tas2552_reg_defs[] which is used as part of a overall larger struct called regmap_config on line 678.

tas2552_reg_defs[] should be set to DEFAULT REGISTER VALUES

On line 707 this struct is passed to devm_regmap_init_i2c, which calls regmap_get_i2c_bus (this passes because there are 2 other chips working on the same i2c line), and devm_regmap_init.

devm_regmap_init calls regmap_init which then puts the register map into sysfs. This is actually very useful for debugging.

At this point, no registers have been written, as they are supposedly DEFAULT VALUES.


So here is where things get hosed up.

The first time a write to the chip supposedly occurs is on line 595. The function snd_soc_update_bits returns 0 on success, or a negative error code otherwise. Now what happens here is this logic:

C code:
int snd_soc_component_update_bits(struct snd_soc_component *component,
	unsigned int reg, unsigned int mask, unsigned int val)
{
	bool change;
	int ret;

	if (component->regmap)
		ret = regmap_update_bits_check(component->regmap, reg, mask,
			val, &change);
	else
		ret = snd_soc_component_update_bits_legacy(component, reg,
			mask, val, &change);

	if (ret < 0)
		return ret;
	return change;
}
Oh look, if you have a regmap then regmap_update_bits_check is called, which to be fair to this function does fail and does return a negative error number, however the driver code itself does not check anywhere the return value and goes on it's merry way like nothing bad ever happened. This isn't the real horror though. Sure it's bad, but not the real travisty of the story.

The real problem is when sound_soc_read is called. This is where things get hosed up. snd_soc_read calls snd_soc_component_read which has this logic:

code:
int snd_soc_component_read(struct snd_soc_component *component,
	unsigned int reg, unsigned int *val)
{
	int ret;

	if (component->regmap)
		ret = regmap_read(component->regmap, reg, val);
	else if (component->read)
		ret = component->read(component, reg, val);
	else
		ret = -EIO;

	return ret;
}
regmap_read calls _regmap_read which has this logic in it:

code:
static int _regmap_read(struct regmap *map, unsigned int reg,
			unsigned int *val)
{
	int ret;
	void *context = _regmap_map_get_context(map);

	WARN_ON(!map->reg_read);

	if (!map->cache_bypass) {
		ret = regcache_read(map, reg, val);
		if (ret == 0)
			return 0;
	}

	if (map->cache_only)
		return -EBUSY;

	if (!regmap_readable(map, reg))
		return -EIO;

	ret = map->reg_read(context, reg, val);
	if (ret == 0) {
#ifdef LOG_DEVICE
		if (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
			dev_info(map->dev, "%x => %x\n", reg, *val);
#endif

		trace_regmap_reg_read(map, reg, *val);

		if (!map->cache_bypass)
			regcache_write(map, reg, *val);
	}

	return ret;
}
And there's the problem. If you don't set cache_bypass as a flag (which is NOT THE DEFAULT) it reads FROM THE MODIFIED ARRAY AND NOT THE loving CHIP.

At this point you get a success on return, and it creates a perfect loving storm of making it look like i2c is working.

Three weeks. I will never EVER trust wrappers around read/writes again.

FlapYoJacks
Feb 12, 2009
Buildroot-2016.11-rc1 has been released. Seems to be a pretty solid update.

Hunter2 Thompson
Feb 3, 2005

Ramrod XTreme
A little late to the show, but I also know the pain of poorly-used regmap and wrangling sound_soc drivers, WM8962 in my case.

Regmap is actually pretty dang cool, but if misused it creates major headaches. The default values array thing is kind of hacky because I wouldn't depend on them not changing between codec chip revisions, but I get that it satisfies some needs. Because of that I'm conservative about what goes into the default values array.

If you're not too worried about the power or latency costs of read/modify/write cycles when changing codec settings, just disable regmap caching entirely, which it looks like you've done by setting the cache bypass flag. The other way of disabling it is at regmap init, there's an option for a cache type and REGCAHCE_NONE is valid.

http://lxr.free-electrons.com/source/include/linux/regmap.h?v=3.2

Also, Mark Brown, the author of regmap, has answered my questions before on the alsa dev irc channel.

salisbury shake
Dec 27, 2011
edit: I am an idiot and this is not the general Linux questions thread

salisbury shake fucked around with this message at 15:21 on Dec 5, 2016

FlapYoJacks
Feb 12, 2009

meatpotato posted:

A little late to the show, but I also know the pain of poorly-used regmap and wrangling sound_soc drivers, WM8962 in my case.

Regmap is actually pretty dang cool, but if misused it creates major headaches. The default values array thing is kind of hacky because I wouldn't depend on them not changing between codec chip revisions, but I get that it satisfies some needs. Because of that I'm conservative about what goes into the default values array.

If you're not too worried about the power or latency costs of read/modify/write cycles when changing codec settings, just disable regmap caching entirely, which it looks like you've done by setting the cache bypass flag. The other way of disabling it is at regmap init, there's an option for a cache type and REGCAHCE_NONE is valid.

http://lxr.free-electrons.com/source/include/linux/regmap.h?v=3.2

Also, Mark Brown, the author of regmap, has answered my questions before on the alsa dev irc channel.

Also a little late to this, but yes; I agree; the original intentions of regmap are awesome and make for some great power savings techniques. The true blame is like, 10% regmap, 45% the driver, 45% me for failing to diagnose it correctly for 2 weeks.


In other news! Buildroot 2016.11 was just released, looks like a solid update! One of the best features though is that it will now use the hosts cmake if it's available. This saves me almost 10 minutes of compile time!

mdxi
Mar 13, 2006

to JERK OFF is to be close to GOD... only with SPURTING

This is a cool thread, with lots of neat info.

I have a personal project that's all about very low-power computing, so I'm basically in the embedded space on the hardware side (though I'm using regular old Linux on the software side).

I'm evaluating the PCEngines APU2 at the moment, but if anyone knows about other SBCs with mSATA or M.2 onboard, I would love to hear about them.

FlapYoJacks
Feb 12, 2009
Up to 60 hours this week, completely my fault. I said that all the hardware on our new board verified and it didn't. I can talk to the camera on our new board via I2C, I can read, write, and configure it (also in uboot.)

However when I ask the drat thing for a picture it pukes, tripping the MIPI_CSI_ERR1 register of the IMX.6 with 0x3, which translates back to:

Start of Transmission Error on data lane 1 and 0 (no synchronization achieved) on the Mipi bus.

Here's the funny thing: we are using a OV5640 on our board with the exact same driver, filing system, and even schematic as the WCAM-ADPT-G; except for one thing: We added 600Ohm, 300mA Ferrite beads to the clock lines to reduce EMI, so now to test I have to remove 7 0201 beads and replace them with 0hm resistors. :suicide:

Popete
Oct 6, 2009

This will make sure you don't suggest to the KDz
That he should grow greens instead of crushing on MCs

Grimey Drawer
How many MIPI lanes are you using? I had a project awhile back with two displays on an i.MX6 that used both the direct MIPI interface (2 lanes) to the i.MX and then a 4 lane MIPI interface display that was connected via the i.MX LVDS interface to a LVDS/MIPI bridge and then to the display. I never quite got the bridge interface to work but the 2 lane direct MIPI interface was fairly straightforward.

FlapYoJacks
Feb 12, 2009

Popete posted:

How many MIPI lanes are you using? I had a project awhile back with two displays on an i.MX6 that used both the direct MIPI interface (2 lanes) to the i.MX and then a 4 lane MIPI interface display that was connected via the i.MX LVDS interface to a LVDS/MIPI bridge and then to the display. I never quite got the bridge interface to work but the 2 lane direct MIPI interface was fairly straightforward.

The ov5640 uses two lanes. Its probably the beads, on the plus side I am finally getting soldering tweezers!

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

I have a beaglebone black and I used scp to transfer a file from my desktop to the beaglebone today. The beaglebone came from adafruit with debian pre-installed.

I sent it as root user, like: scp ./foo root@192.168.1.72:/home/debian/

I meant to do it as the default debian user, but wasn't thinking.
So anyways when I ran this command it didn't ask me for a password and just wrote the file as root for me. WTF?

e: i know there's some way to set up SSH keys or something so that you don't get prompted for pw, but I always forget how this works, and I'm pretty sure I never set this device up for that, sooo...

peepsalot fucked around with this message at 03:49 on Dec 20, 2016

Storysmith
Dec 31, 2006

peepsalot posted:

I have a beaglebone black and I used scp to transfer a file from my desktop to the beaglebone today. The beaglebone came from adafruit with debian pre-installed.

I sent it as root user, like: scp ./foo root@192.168.1.72:/home/debian/

I meant to do it as the default debian user, but wasn't thinking.
So anyways when I ran this command it didn't ask me for a password and just wrote the file as root for me. WTF?

e: i know there's some way to set up SSH keys or something so that you don't get prompted for pw, but I always forget how this works, and I'm pretty sure I never set this device up for that, sooo...

Try running (as root)
code:

cat /root/.ssh/authorized_keys
That'd establish if your key is in there, which would be the mechanism you're talking about.

Alternately, there's a setting that reuses existing ssh connections via a shared socket setup so that `ssh root@bbb` creates a socket and the next `ssh root@bbb` (or `scp`) reuses it so you don't have to wait on kex to happen again, but I thought that required auth to still happen (and I'm away from my setup where I could easily test this right now).

Adding more levels of -v flags to get more debug output will shine some light as to how auth (if any) is happening.

You can do some interesting stuff with .ssh/config to specify the Debian user as default and add aliases there for your ssh hosts, btw. May be worth it if the box isn't running avahi and therefore is hard to find on a DHCP network.

Adbot
ADBOT LOVES YOU

peepsalot
Apr 24, 2007

        PEEP THIS...
           BITCH!

Storysmith posted:

Try running (as root)
code:
cat /root/.ssh/authorized_keys
code:
cat: /root/.ssh/authorized_keys: No such file or directory
there is no .ssh dir under /root at all

Storysmith posted:

Adding more levels of -v flags to get more debug output will shine some light as to how auth (if any) is happening.
code:
peeps@peeps-ThinkPad-W510:~$ touch foo
peeps@peeps-ThinkPad-W510:~$ scp -v foo root@192.168.1.72:/home/debian/
Executing: program /usr/bin/ssh host 192.168.1.72, user root, command scp -v -t /home/debian/
OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to 192.168.1.72 [192.168.1.72] port 22.
debug1: Connection established.
debug1: identity file /home/peeps/.ssh/id_rsa type 1
debug1: identity file /home/peeps/.ssh/id_rsa-cert type -1
debug1: identity file /home/peeps/.ssh/id_dsa type -1
debug1: identity file /home/peeps/.ssh/id_dsa-cert type -1
debug1: identity file /home/peeps/.ssh/id_ecdsa type -1
debug1: identity file /home/peeps/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/peeps/.ssh/id_ed25519 type -1
debug1: identity file /home/peeps/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.0p1 Debian-4+deb7u6
debug1: match: OpenSSH_6.0p1 Debian-4+deb7u6 pat OpenSSH* compat 0x04000000
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ECDSA 74:4c:b9:73:85:62:82:f9:c7:17:5d:9f:72:b1:e9:8f
debug1: Host '192.168.1.72' is known and matches the ECDSA host key.
debug1: Found key in /home/peeps/.ssh/known_hosts:31
debug1: ssh_ecdsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
Debian GNU/Linux 7

BeagleBoard.org Debian Image 2015-11-12

Support/FAQ: [url]http://elinux.org/Beagleboard:BeagleBoneBlack_Debian[/url]

default username:password is [debian:temppwd]

debug1: Authentication succeeded (none).
Authenticated to 192.168.1.72 ([192.168.1.72]:22).
debug1: channel 0: new [client-session]
debug1: Requesting [email]no-more-sessions@openssh.com[/email]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LC_PAPER = en_US.UTF-8
debug1: Sending env LC_ADDRESS = en_US.UTF-8
debug1: Sending env LC_MONETARY = en_US.UTF-8
debug1: Sending env LC_NUMERIC = en_US.UTF-8
debug1: Sending env LC_TELEPHONE = en_US.UTF-8
debug1: Sending env LC_IDENTIFICATION = en_US.UTF-8
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env LC_MEASUREMENT = en_US.UTF-8
debug1: Sending env LC_TIME = en_US.UTF-8
debug1: Sending env LC_NAME = en_US.UTF-8
debug1: Sending command: scp -v -t /home/debian/
Sending file modes: C0644 0 foo
Sink: C0644 0 foo
foo                                                                                                                                         100%    0     0.0KB/s   00:00
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 3040, received 1856 bytes, in 0.1 seconds
Bytes per second: sent 34492.5, received 21058.6
debug1: Exit status 0

  • Locked thread