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

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.

Related

How to port a linux driver , which is compiled in 2.6 kernel ,without compiling in other new version of kernel

Thanks to every one,
This is the question asked in one of the interview i faced.
I have a Linux device driver which was compiled in Linux kernel version 2.6.I would like to port the same driver in a Linux PC which has kernel 3.X without compiling in new versions.
Is it possible ? If it is possible please let me know how. If it is not possible please let me know why not ?
Thanks & Regards
Siva
No you cannot port module which is compiled for one version to other version.
The reason is as follows
Modules are strongly tied to the data structures and function prototypes defined in a particular kernel version;
the interface seen by a module can change significantly from one kernel version to
the next. This is especially true of development kernels, of course
The kernel does not just assume that a given module has been built against the
proper kernel version. One of the steps in the build process is to link your module
against a file (called vermagic.o) from the current kernel tree; this object contains a
fair amount of information about the kernel the module was built for, including the
target kernel version, compiler version, and the settings of a number of important
configuration variables. When an attempt is made to load a module, this information
can be tested for compatibility with the running kernel. If things don’t match,
the module is not loaded; instead, you see something like:
# insmod hello.ko
Error inserting './hello.ko': -1 Invalid module format
A look in the system log file (/var/log/messages or whatever your system is configured
to use) will reveal the specific problem that caused the module to fail to load.
Kernel interfaces often change between releases. If you are writing a module that is
intended to work with multiple versions of the kernel (especially if it must work
across major releases), you likely have to make use of macros and #ifdef constructs
to make your code build properly.
now it's not possible:
usually, a "driver" is a binary kernel-module
porting will involve code-changes to the kernel module. if you change the code, you need to compile it, in order to get a binary.
since kernel modules run in kernel space, it is crucial that they are robust. since parts of the kernel-API change every now and then, trying to use a module compiled for kernel-X with another kernel-Y, might either not load because of missing symbols (if you are lucky) or lead to a kernel panic because semantics have changed.
btw, all this is not really related to 2.6.x vs 3.y, but holds true for any kernel version
but then: of course in theory it is possible to "write" a kernel-module as binary code in your favourite hex-editor, without resorting to compilers and such. this would allow you to "port" a driver from one kernel to another without recompilation. i guess this is not for humans though...

How to run aout on linux?

The question is how to execute aout-format binary (I mean old format which for example used on FreeBSD before it has migrated to ELF) on Linux system. Is there a possibility to do so without extra coding (is there some existing solution)? Probably it should be in form of kernel module or patch for the Linux kernel. Another solution could be user-space launcher (may be even run-time linker). I have searched for something similar but was unable to found something. I have not yet checked difference in system calls interfaces, if you have some comments about that, you are welcome to provide them.
P.S. I know that writing user-space launcher for aout static binary is quite trivial but the question is about some existing solution.
Check for CONFIG_BINFMT_AOUT in your kernel config.
If your kernel has /proc/config.gz:
zgrep CONFIG_BINFMT_AOUT /proc/config.gz
On Ubuntu and the like:
grep CONFIG_BINFMT_AOUT /boot/config-$(uname -r)
Kernel option was CONFIG_BINFMT_AOUT, not sure if it's still around or necessary.

Stripping down a kernel in linux?

I recently read a post (admittedly its a few years old) and it was advice for fast number-crunching program:
"Use something like Gentoo Linux with 64 bit processors as you can compile it natively as you install. This will allow you to get the maximum punch out of the machine as you can strip the kernel right down to only what you need."
can anyone elaborate on what they mean by stripping down the kernel? Also, as this post was about 6 years old, which current version of Linux would be best for this (to aid my google searches)?
There is some truth in the statement, as well as something somewhat nonsensical.
You do not spend resources on processes you are not running. So as a first instance I would try minimise the number of processes running. For that we quite enjoy Ubuntu server iso images at work -- if you install from those, log in and run ps or pstree you see a thing of beauty: six or seven processes. Nothing more. That is good.
That the kernel is big (in terms of source size or installation) does not matter per se. Many of this size stems from drivers you may not be using anyway. And the same rule applies again: what you do not run does not compete for resources.
So think about a headless server, stripped down -- rather than your average desktop installation with more than a screenful of processes trying to make the life of a desktop user easier.
You can create a custom linux kernel for any distribution.
Start by going to kernel.org and downloading the latest source. Then choose your configuration interface (you have the choice of console text, 'config', ncurses style 'menuconfig', KDE style 'xconfig' and GNOME style 'gconfig' these days) and execute ./make whateverconfig. After choosing all the options, type make to create your kernel. Then make modules to compile all the selected modules for this kernel. Then, make install will copy the files to your /boot directory, and make modules_install, copies the modules. Next, go to /boot and use mkinitrd to create the ram disk needed to boot properly, if needed. Then you'll add the kernel to your GRUB menu.lst, by editing menu.lst and copying the latest entry and adding a similar one pointing to the new kernel version.
Of course, that's a basic overview and you should probably search for 'linux kernel compile' to find more detailed info. Selecting the necessary kernel modules and options takes a bit of experience - if you choose the wrong options, the kernel might not be bootable and you'll have to start over, which is a pain because selecting the options and compiling the kernel can take 15-30 minutes.
Ultimately, it isn't going to make a large difference to compile a stripped-down custom kernel unless your given task is very, very performance sensitive. It makes sense to remove things you're never going to use from the kernel, though, like say ISDN support.
I'd have to say this question is more suited to SuperUser.com, by the way, as it's not quite about programming.

Arguments to kernel

Is there anything that the kernel need to get from the boot loader.Usually the kernel is capable of bringing up a system from scratch, so why does it require anything from boot-loader?
I have seen boot messages from kernel like this.
"Fetching vars from bootloader... OK"
So what exactly are the variables being passed?
Also how are the variables being passed from the boot-loader? Is it through stack?
The kernel accept so called command-line options, that are text based. This is very useful, because you can do a lot of thing without having to recompile your kernel. As for the argument passing, it is architecture dependent. On ARM it is done through a pointer to a location in memory, or a fixed location in memory.
Here is how it is done on ARM.
Usually a kernel is not capable of booting the machine from scratch. May be from the bios, but then it is not from scratch. It needs some initialisation, this is the job of the bootloader.
There are some parametres that the Linux kernel accepts from the bootloader, of which what I can remember now is the vga parametre. For example:
kernel /vmlinuz-2.6.30 root=/dev/disk/by-uuid/3999cb7d-8e1e-4daf-9cce-3f49a02b00f2 ro vga=0x318
Have a look at 10 boot time parameters you should know about the Linux kernel which explains some of the common parametres.
For the Linux kernel, there are several things the bootloader has to tell the kernel. It includes things like the kernel command line (as several other people already mentioned), where in the memory the initrd has been loaded and its size, if an initrd is being used (the kernel cannot load it by itself; often when using an initrd, the modules needed to acess storage devices are within the initrd, and it can also have to do some quite complex setup before being able to access the storage), and several assorted odds and ends.
See Documentation/x86/boot.txt (link to 2.6.30's version) for more detail for the traditional x86 architecture (both 32-bit and 64-bit), including how these variables are passed to the kernel setup code.
The bootloader doesn't use a stack to pass arguments to the kernel. At least in the case of Linux, there is a rather complex memory structure that the bootloader fills in that the kernel knows how to parse. This is how the bootloader points the kernel to its command line. See Documentaion/x86/boot.txt for more info.
Linux accepts variables from the boot loader to allow certain options to be used. I know that one of the things you can do is make it so that you don't have to log-in (recovery mode) and there are several other options. It mainly just allows fixes to be done if there's an issue with something or for password changing. This is how the Ubuntu Live-CD boots Linux if you select to use another option.
Normally the parameters called command line parameters, which is passed to kernel module from boot loader. Bootloader use many of the BIOS interrupts to detect,
memory
HDD
Processor
Keyboard
Screen
Mouse
ETC...
and all harwares details are going to be detected at boot time, that is in real mode, then pass this parameters to Kernel.

How to find the process which is cosuming the most i/o in linux?

When I use top the iowait on the host is really high.
iostat tells me which disk is utilized more but I want to find out which process is the culprit?
I am trying to find this out on a red hat linux host. Any suggestions.
EDIT: My linux flavor does not either have atop or ntop and since building kernel is not an option for me don't ask me why :) (since this is not my personal box). are there any other alternatives
I usually use atop. There's a really good article at Debian Package A Day about it. It does require kernel patching (although Ubuntu already has the patch applied, I'm not sure about any other distributions.)
Use iotop.
Or you can get it standalone, it's a simple python script which requires a recent kernel (can't remember, but at least > 2.6.20)

Resources