Linux, CPU-architecture in which file stored - linux

I like to know, in which file the value for the CPU architecture is stored on Linux e.g. x86_64.
I know several methods (shell commands) in order to access this value like lscpu or uname -a.
Furthermore I'm aware of the Qt-Method QSysInfo::currentCpuArchitecture(). And they all provide the required information.
But I like to create an OS-Interface which retrieves the information of the underlying operating system (in my case Linux) only by using "Linux-Tools" like information from files in /proc/....
I also know that I can run a shell command in my program by using popen() and access the results by the std streamer classes. That's no problem. But unfortunately we don't like run shell commands in our software.
I have looked in several files like
/proc/version, /proc/cpuinfo, /proc/devices or in files in subfolders of /proc.
But unfortunately it seems to me as if I always overlooked this piece of information. I'm sure that it has to be in a file because the method QSysInfo::currentCpuArchitecture() access this information, too.
So if somebody knows where this information is placed on Linux I would be happy if he or she let me know.
With kind regards

According man lscpu
lscpu gathers CPU architecture information from sysfs,
/proc/cpuinfo ...
looking for the information under /proc and cpuinfo was the right idea, since the information is there, but not in the format you were expecting. It is somehow "hidden" in line flags. You like to look for lm (long mode).
cat /proc/cpuinfo | grep "flags\| lm "
If the flag for long mode is set you are on x86_64.
Thanks / Credits to
What do the flags in /proc/cpuinfo mean?
CPUID, bit 29 (LM)
How the information is gathered and processed you can find in sys-utils/lscpu.c, in example from line 369-378.
Other CPU modes are
Real Mode, 16 bit CPU, Intel 8086 or 8080 emulation mode, all x86 CPU start in this mode after reset
Protected Mode, 32-bit CPU

Related

How to get distro name and version from linux kernel code?

I am looking if there is any API through which we can get OS distribution name and version from a Linux kernel module?
For example, I am using SLES 12 service pack 4. This information is present in /etc/os-release file. I want to know if there is any way to get this information from kernel code.
linux:/ # cat /etc/os-release
NAME="SLES"
VERSION="12-SP4"
VERSION_ID="12.4"
PRETTY_NAME="SUSE Linux Enterprise Server 12 SP4"
ID="sles"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:12:sp4"
linux:/ #
There's no kernel API for detecting the current OS distribution, simply because it's not really needed. The Linux kernel itself is distribution-agnostic, and it couldn't care less which distribution is being run on top of it (having the kernel depend on what's being run on top of it wouldn't make much sense).
If you really want, you can open, read and parse the file yourself from kernel space. See more in this other post for an example, and in particular this answer for modern kernels. In any case, remember that filesystem interaction from kernel space is generally discouraged, and could easily lead to bugs and compromise the security of the kernel if done wrong, so be careful.
If you are developing a kernel module, I would suggest you to parse the /etc/os-release file from userspace when compiling/installing the module and use a set of #defines, or even module parameters. In any case, you should ask yourself why you need this information in kernel code in the first place, as you really shouldn't.

How to get the CPU MHz (in /proc/cpuinfo) by the syscall?

In the /proc/cpuinfo, I find a strange parameter "cpu MHz" which is changing all the time. I want to study how it works. Does there exist some syscall that can help me get this parameter? I wish this syscall can help me know how to calculate the cpu MHz.
No, there is no syscall that will tell you the current speed (MHz) of your CPU. If you want to know the value without writing a kernel module for it, you can read the /proc/cpuinfo file, which is there exactly for this purpose (making this info available to user space programs). There also is a good post here which lists more ways to obtain such information.
If you want to know how the values are calculated you can look at the source code of the Linux kernel. In particular, the fs/proc/cpuinfo.c file is a good starting point.
you might find the information in the /sys filesystem easier to parse:
$ grep . /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq:900014
/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq:900016
/sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq:883064
/sys/devices/system/cpu/cpu3/cpufreq/scaling_cur_freq:862357
under /sys/devices/system/cpu/cpu*/ you will find more interesting properties of each CPU on your system, all of them in an easy-to-parse format (usually just a single line)

Display information about hardware in Linux/Unix

I want to display information about my hardware, and there are three commands to do that:
dmesg
lshal
dmidecode
but I'm confused between these three commands.
So what is the difference among them?
I would like to suggest that you use lshw, a very helpful tool to list your hardware. From its man page:
lshw is a small tool to extract detailed information on the hardware configuration of the machine. It can report exact memory configuration, firmware version, mainboard configuration, CPU version and speed, cache configuration, bus speed, etc. on DMI-capable x86 or IA-64 systems and on some PowerPC machines (PowerMac G4 is known to work).
The dmesg command is used to write the kernel messages in Linux and other Unix-like operating systems to standard output.
From man pages:
lshal - list HAL devices
lshal is a utility for displaying items in the HAL device database.
For more information about both the big picture and specific HAL
properties, refer to the HAL spec which can be found in
/usr/share/doc/hal-0.5.14/spec/hal-spec.html depending on the
distribution.
dmidecode - DMI Table Decoder
dmidecode is a tool for dumping a computer's DMI (some say SMBIOS )
table contents in a human-readable format. This table contains a
description of the system's hardware components, as well as other
useful pieces of information such as serial numbers and BIOS revision.
Thanks to this table, you can retrieve this information without having
to probe for the actual hardware. While this is a good point in terms
of report speed and safeness, this also makes the presented
information possibly unreliable.
The dmesg command is used to write the kernel messages in Linux and other Unix-like operating systems to standard output (which by default is the display screen).
lshal is a utility for displaying items in the HAL device database.
dmidecode is a tool for dumping a computer's DMI (some say SMBIOS ) table contents in a human-readable format. This table contains a description of the system's hardware components, as well as other useful pieces of information such as serial numbers and BIOS revision. Thanks to this table, you can retrieve this information without having to probe for the actual hardware. While this is a good point in terms of report speed and safeness, this also makes the presented information possibly unreliable.
I would suggest to go for "dmesg" and use the options as per you need to obtain information about the hardware on a system.
dmesg [options]

Hardware recognition in user space Linux

I want to be able to inspect my Linux machine hardware in C.
How do I get the information that appear in dmesg in C ?
For example, for keyboard the message is input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
I want to get in my program the label, AT Translated Set 2, and the path, /devices/platform/i8042/serio0/input/input0.
Any idea how to do so ?
amit
You can also look at the contents of files in /proc.
/proc/version, /proc/ioports, /proc/iomem, /proc/meminfo, and others have a lot of information in them.
The files under /proc/bus have additional information about the system's hardware devices.
I'd also recommend looking at the source code for usbutils and pciutils for example code to get the output from the lsusb and lspci commands respectively.
It uses the klogctl call.
Best thing is to read the source code yourself, it can be downloaded here: util-linux
You would want to use libhal, and connect to the hal daemon. If HAL isn't there, look for a mounted sysfs partition. Check out /sys/devices, or work backwards through /sys/bus.
If neither HAL nor sysfs is available, reconsider your approach or restrict your scope.

How to discover the machine type?

I would like to discover the machine architecture type of a big number of machines. I have the hostname of each machine. The machines have Debian 4 linux, SunOS 9, SunOS 10 or Apple Darwin. All are unix-like, but with minor differences.
I would like to know:
- architecture (x86, x86_64, ia64, sparc, powerpc...)
- processor type (intel pentium, pentium pro, pentium II, sparc, powerpc, itanium, athlon, core 2 duo, cytrix, etc...)
- number of processors
Beware, I want the "type" of the machine. The stupid approach using 'uname' does not work on Sun and it also returns things like 'i686' when the machine is in fact 'x86_64' but the operating system is 32 bits. /proc/cpuinfo doesn't work neither, and things get even more complicated because some machines dont have a C compiler installed (I'm sure they all have sh, perhaps python or perl, dunno).
Thanks in advance!! :)
arch ; uname -a
arch is the standard way to get the name of the CPU instruction set. uname -a gets a bunch of stuff about the OS. uname withouth the a gets the OS name.
However programmatically speaking, the equivalent to arch is uname -m.
You can try the following Perl one-liner:
perl -MConfig -e 'print "$Config{myarchname}\n";'
I know on Mac OS X Leopard with Perl 5.10.0 it prints "i386-darwin". I don't know of a way in Perl to get the actual processor name - your best bet is probably C since it's a fairly limited set of possibilities. You can get at a C compiler's predefined macros from Perl:
perl -MConfig -e 'print join("\n", split(/ /, $Config{cppsymbols})), "\n";'
This will list C macros like __LITTLE_ENDIAN__ and __MACH__ for Mach-O format and __i386__ (on Leopard at least), as well as the useless ones like __GNUC__ and __STDC__. Of course, all of this help assumes you have Perl on all machines. If not, I'm sure other languages have similar facilities to help you.
I would suggest you look at the facter component of the Puppet system. From the URL http://reductivelabs.com/projects/facter/.
A cross-platform Ruby library for retrieving facts from operating systems. Supports multiple resolution mechanisms, any of which can be restricted to working only on certain operating systems or environments. Facter is especially useful for retrieving things like operating system names, IP addresses, MAC addresses, and SSH keys.
Why /proc/cpuinfo doesn't work?
I don't know all of the OSs you mentioned, but I think it give quite detailed information under Linux. At least, with the model of CPU, other informations can be looked up from a data table.
The software can only see what the OS let it to see, so if the OS doesn't provide informations like /proc/cpuinfo, then you'll have no way to know it.
reply to the comments:
I am not saying look for /proc/cpuinfo for all the OS. It's a two steps method: first you find out which OS it is using uname, then look for the OS specific position for the cpu info.
This is not a complete answer, but it may help you reach your goal.
arch does not work on HP-UX Itanium, and it does not have the /proc filesystem, as you mentioned.
This explains how to determine the endianness (byte order) the O/S is using simply with shell commands. It works on at least 4 major Unixes (Linux x86_64, Solaris Sparc, AIX/Power, HP-UX Itanium). If you know the byte ordering you can deduce a lot about which CPU you're dealing with, based on this source.
For instance, if Solaris won't tell you the correct architecture, but you see that it's big endian, you at least know you're not on x86_64, and probably Sparc.
Finally, for Sparc you can do this to determine whether the OS is running in 32 or 64 bit mode:
# isalist -v
sparcv9+vis2 sparcv9+vis sparcv9 sparcv8plus+vis2 sparcv8plus+vis sparcv8plus sparcv8 sparcv8-fsmuld sparcv7 sparc
If it says 'sparcv9' it's 64 bit, sparcv8 is 32
The use of uname -a will bring you to much information, so you have to search for the information you want to have.
Just use:
uname -i
for the hardware platform
or
uname -m
for the machine hardware name

Resources