Where does uname get its information from?











up vote
38
down vote

favorite
7












Where does uname really get its information from?



I figure this is something that should be straightforward. Unfortunately, I can't find any header containing just that information.



Say someone wanted to change the basic output of uname/uname -s from Linux to something else (essentially, renaming the kernel).



How would he/she go about doing that the proper way (that is, changing the source)?










share|improve this question




























    up vote
    38
    down vote

    favorite
    7












    Where does uname really get its information from?



    I figure this is something that should be straightforward. Unfortunately, I can't find any header containing just that information.



    Say someone wanted to change the basic output of uname/uname -s from Linux to something else (essentially, renaming the kernel).



    How would he/she go about doing that the proper way (that is, changing the source)?










    share|improve this question


























      up vote
      38
      down vote

      favorite
      7









      up vote
      38
      down vote

      favorite
      7






      7





      Where does uname really get its information from?



      I figure this is something that should be straightforward. Unfortunately, I can't find any header containing just that information.



      Say someone wanted to change the basic output of uname/uname -s from Linux to something else (essentially, renaming the kernel).



      How would he/she go about doing that the proper way (that is, changing the source)?










      share|improve this question















      Where does uname really get its information from?



      I figure this is something that should be straightforward. Unfortunately, I can't find any header containing just that information.



      Say someone wanted to change the basic output of uname/uname -s from Linux to something else (essentially, renaming the kernel).



      How would he/she go about doing that the proper way (that is, changing the source)?







      linux kernel source






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 23 '15 at 22:47









      don_crissti

      48.9k15129157




      48.9k15129157










      asked Jun 13 '14 at 13:56









      user237251

      306134




      306134






















          7 Answers
          7






          active

          oldest

          votes

















          up vote
          26
          down vote













          The uname utility gets its information from the uname() system call. It populates a struct like this (see man 2 uname):



                 struct utsname {
          char sysname; /* Operating system name (e.g., "Linux") */
          char nodename; /* Name within "some implementation-defined
          network" */
          char release; /* Operating system release (e.g., "2.6.28") */
          char version; /* Operating system version */
          char machine; /* Hardware identifier */
          #ifdef _GNU_SOURCE
          char domainname; /* NIS or YP domain name */
          #endif
          };


          This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodename, machine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.



          However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.






          share|improve this answer



















          • 2




            The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
            – Scott
            Jun 13 '14 at 19:15








          • 2




            This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
            – Gilles
            Jun 14 '14 at 22:35










          • @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
            – goldilocks
            Jun 16 '14 at 12:14








          • 2




            @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
            – Gilles
            Jun 16 '14 at 13:20






          • 1




            @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
            – goldilocks
            Jun 16 '14 at 13:30




















          up vote
          23
          down vote













          The data is stored in init/version.c:



          struct uts_namespace init_uts_ns = {
          .kref = {
          .refcount = ATOMIC_INIT(2),
          },
          .name = {
          .sysname = UTS_SYSNAME,
          .nodename = UTS_NODENAME,
          .release = UTS_RELEASE,
          .version = UTS_VERSION,
          .machine = UTS_MACHINE,
          .domainname = UTS_DOMAINNAME,
          },
          .user_ns = &init_user_ns,
          .proc_inum = PROC_UTS_INIT_INO,
          };
          EXPORT_SYMBOL_GPL(init_uts_ns);


          The strings themselves are in include/generated/compile.h:



          #define UTS_MACHINE "x86_64"
          #define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"


          and in include/generated/utsrelease.h:



          #define UTS_RELEASE "3.14.0-v2-v"


          UTS_SYSNAME may be defined in include/linux/uts.h



          #ifndef UTS_SYSNAME
          #define UTS_SYSNAME "Linux"
          #endif


          or as a #define in makefiles



          Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:



          # hostname
          hell
          # unshare --uts /bin/bash
          # echo test > /proc/sys/kernel/hostname
          # hostname
          test
          # exit
          # hostname
          hell





          share|improve this answer























          • This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
            – Faheem Mitha
            Jun 16 '14 at 18:12












          • +1 for unshare. Somehow I managed to miss this command until today. Thanks!
            – Tino
            Jan 20 '17 at 11:39


















          up vote
          8
          down vote













          With the help of a Linux Cross Reference and your mention of /proc/sys/kernel/ostype, I tracked ostype to include/linux/sysctl.h,
          where a comment says that names are added by calling register_sysctl_table.



          So where is that called from? One place is kernel/utsname_sysctl.c, which includes include/linux/uts.h, where we find:




          /*
          * Defines for what uname() should return
          */
          #ifndef UTS_SYSNAME
          #define UTS_SYSNAME "Linux"
          #endif



          So, as the kernel documentation states:




          The only way to tune these values is to rebuild the kernel




          :-)






          share|improve this answer






























            up vote
            5
            down vote













            As commented elsewhere, the information come with the uname syscall, which information is hard-coded in the running kernel.



            The version part is normally set when compiling a new kernel by the Makefile:



            VERSION = 3
            PATCHLEVEL = 15
            SUBLEVEL = 0
            EXTRAVERSION =


            when I had time to play compiling my kernels, I used to add things over there in EXTRAVERSION; that gave you uname -r with things like 3.4.1-mytestkernel.



            I do not fully understand it, but I think that the rest of the information is setup in the Makefile also around line 944:



            # ---------------------------------------------------------------------------

            # KERNELRELEASE can change from a few different places, meaning version.h
            # needs to be updated, so this check is forced on all builds

            uts_len := 64
            define filechk_utsrelease.h
            if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then
            echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;
            exit 1;
            fi;
            (echo #define UTS_RELEASE "$(KERNELRELEASE)";)
            endef

            define filechk_version.h
            (echo #define LINUX_VERSION_CODE $(shell
            expr $(VERSION) * 65536 + 0$(PATCHLEVEL) * 256 + 0$(SUBLEVEL));
            echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
            endef

            $(version_h): $(srctree)/Makefile FORCE
            $(call filechk,version.h)

            include/generated/utsrelease.h: include/config/kernel.release FORCE
            $(call filechk,utsrelease.h)

            PHONY += headerdep
            headerdep:
            $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1
            $(srctree)/scripts/headerdep.pl -I$(srctree)/include


            For the rest of the data, the sys_uname syscall is generated using macros (in a quite convoluted way), you can start from here if you feel adventurous.



            Probably the best way to change such information is writing a kernel module to override the uname syscall; I never did that but you can find info in this page at section 4.2 (sorry, no direct link). Notice however that that code is referring to a quite old kernel (now Linux kernel has uts namespaces, whatever they mean) so you will need to change it probably a lot.






            share|improve this answer























            • Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
              – user237251
              Jun 13 '14 at 17:48










            • @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
              – JAB
              Jun 13 '14 at 17:55












            • @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
              – user237251
              Jun 17 '14 at 17:14




















            up vote
            2
            down vote













            While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.



            man 2 uname



            should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.



            You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.






            share|improve this answer

















            • 3




              If you do strace uname, it will confirm that the uname system call is used.
              – Graeme
              Jun 13 '14 at 14:11


















            up vote
            1
            down vote













            Proper way to change uname would be to change compile headers and re-compile like others suggested. But I am not sure why you would want to go through that much trouble when you can do something like,



            alias uname 'uname \!* | sed s/2.6.13/2.6.52/'


            or even



            alias uname 'echo whatever'





            share|improve this answer






























              up vote
              0
              down vote













              Rmano's answer got me partway, but the real magic is easier discovered by passing the Q= option in your make commandline in the kernel source directory. it lets you see the details, one of which is a call to a script: echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)". executing that same snippet gives the kernel release number, 4.4.19-00010-ge5dddbf. if you look at the script, it determines the number from the versioning system, and running it with bash -x shows the exact process:



              +++ git rev-parse --verify --short HEAD
              ++ head=e5dddbf
              +++ git describe --exact-match
              ++ '[' -z '' ']'
              ++ false
              +++ git describe
              ++ atag=release/A530_os_1.0.0-10-ge5dddbf
              ++ echo release/A530_os_1.0.0-10-ge5dddbf
              ++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
              ++ git config --get svn-remote.svn.url
              ++ git diff-index --name-only HEAD
              ++ grep -qv '^scripts/package'
              ++ return
              + res=-00010-ge5dddbf
              + echo -00010-ge5dddbf
              -00010-ge5dddbf


              what this shows me is that if I want to build a kernel module to work with my running kernel, I'm on the wrong tagged release and the wrong commit. I need to fix that, and build at least the DTBs (make dtbs) in order to create the generated files with the right version number.





              turns out, even that wasn't enough. I had to replace scripts/setlocalversion to one that simply does:



              #!/bin/sh
              echo -0710GC0F-44F-01QA


              then rebuild the autogenerated files:



              make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs


              then I could build Derek Molloy's sample driver and was able to insmod it successfully. apparently the warning about Module.symvers not being present didn't matter. all Linux was using to determine if the module would work was that localversion string.






              share|improve this answer























                Your Answer








                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "106"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                convertImagesToLinks: false,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f136959%2fwhere-does-uname-get-its-information-from%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                7 Answers
                7






                active

                oldest

                votes








                7 Answers
                7






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                26
                down vote













                The uname utility gets its information from the uname() system call. It populates a struct like this (see man 2 uname):



                       struct utsname {
                char sysname; /* Operating system name (e.g., "Linux") */
                char nodename; /* Name within "some implementation-defined
                network" */
                char release; /* Operating system release (e.g., "2.6.28") */
                char version; /* Operating system version */
                char machine; /* Hardware identifier */
                #ifdef _GNU_SOURCE
                char domainname; /* NIS or YP domain name */
                #endif
                };


                This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodename, machine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.



                However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.






                share|improve this answer



















                • 2




                  The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                  – Scott
                  Jun 13 '14 at 19:15








                • 2




                  This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                  – Gilles
                  Jun 14 '14 at 22:35










                • @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                  – goldilocks
                  Jun 16 '14 at 12:14








                • 2




                  @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                  – Gilles
                  Jun 16 '14 at 13:20






                • 1




                  @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                  – goldilocks
                  Jun 16 '14 at 13:30

















                up vote
                26
                down vote













                The uname utility gets its information from the uname() system call. It populates a struct like this (see man 2 uname):



                       struct utsname {
                char sysname; /* Operating system name (e.g., "Linux") */
                char nodename; /* Name within "some implementation-defined
                network" */
                char release; /* Operating system release (e.g., "2.6.28") */
                char version; /* Operating system version */
                char machine; /* Hardware identifier */
                #ifdef _GNU_SOURCE
                char domainname; /* NIS or YP domain name */
                #endif
                };


                This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodename, machine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.



                However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.






                share|improve this answer



















                • 2




                  The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                  – Scott
                  Jun 13 '14 at 19:15








                • 2




                  This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                  – Gilles
                  Jun 14 '14 at 22:35










                • @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                  – goldilocks
                  Jun 16 '14 at 12:14








                • 2




                  @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                  – Gilles
                  Jun 16 '14 at 13:20






                • 1




                  @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                  – goldilocks
                  Jun 16 '14 at 13:30















                up vote
                26
                down vote










                up vote
                26
                down vote









                The uname utility gets its information from the uname() system call. It populates a struct like this (see man 2 uname):



                       struct utsname {
                char sysname; /* Operating system name (e.g., "Linux") */
                char nodename; /* Name within "some implementation-defined
                network" */
                char release; /* Operating system release (e.g., "2.6.28") */
                char version; /* Operating system version */
                char machine; /* Hardware identifier */
                #ifdef _GNU_SOURCE
                char domainname; /* NIS or YP domain name */
                #endif
                };


                This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodename, machine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.



                However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.






                share|improve this answer














                The uname utility gets its information from the uname() system call. It populates a struct like this (see man 2 uname):



                       struct utsname {
                char sysname; /* Operating system name (e.g., "Linux") */
                char nodename; /* Name within "some implementation-defined
                network" */
                char release; /* Operating system release (e.g., "2.6.28") */
                char version; /* Operating system version */
                char machine; /* Hardware identifier */
                #ifdef _GNU_SOURCE
                char domainname; /* NIS or YP domain name */
                #endif
                };


                This comes directly from the running kernel. I would assume all of the information is hard-coded into it, except perhaps domainname (and as it turns out, also nodename, machine, and release, see comments). The release string, from uname -r, can be set via configuration at compile time, but I doubt very much the sysname field can -- it's the Linux kernel and there's no conceivable reason for it to use anything else.



                However, since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jun 16 '14 at 13:30

























                answered Jun 13 '14 at 14:10









                goldilocks

                61.1k13150204




                61.1k13150204








                • 2




                  The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                  – Scott
                  Jun 13 '14 at 19:15








                • 2




                  This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                  – Gilles
                  Jun 14 '14 at 22:35










                • @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                  – goldilocks
                  Jun 16 '14 at 12:14








                • 2




                  @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                  – Gilles
                  Jun 16 '14 at 13:20






                • 1




                  @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                  – goldilocks
                  Jun 16 '14 at 13:30
















                • 2




                  The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                  – Scott
                  Jun 13 '14 at 19:15








                • 2




                  This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                  – Gilles
                  Jun 14 '14 at 22:35










                • @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                  – goldilocks
                  Jun 16 '14 at 12:14








                • 2




                  @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                  – Gilles
                  Jun 16 '14 at 13:20






                • 1




                  @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                  – goldilocks
                  Jun 16 '14 at 13:30










                2




                2




                The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                – Scott
                Jun 13 '14 at 19:15






                The domainname field is set by the domainname command, using the setdomainname system call. Similarly, the nodename field is set by the hostname command, using the sethostname system call. (The nodename / hostname value may be stored in /etc/nodename.)
                – Scott
                Jun 13 '14 at 19:15






                2




                2




                This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                – Gilles
                Jun 14 '14 at 22:35




                This is irrelevant — the question asked where to change this. So yes, the uname command gets its information from a system call. And where does the system call get its information? (Answer, provided by other posters here: it's hard-coded in the kernel at compile time.)
                – Gilles
                Jun 14 '14 at 22:35












                @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                – goldilocks
                Jun 16 '14 at 12:14






                @Gilles: What's irrelevent? If the answer is "provided by other posters here: it's hard-coded into the kernel..." note I've said the exact same thing: "This comes directly from the running kernel. I would assume all of the information is hard-coded into it...since it is open source, you could change the source code and recompile the kernel to use whatever sysname you want. It is not a config option.
                – goldilocks
                Jun 16 '14 at 12:14






                2




                2




                @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                – Gilles
                Jun 16 '14 at 13:20




                @goldilocks Why would machine ever change? It might not be hardcoded into the kernel because it might adapt to the hardware, but surely then it would be set at boot time and wouldn't change after that. But no: it can be set per process (e.g. to report i686 to 32-bit processed on x86_64). By the way, release can also be customized per process to some extent (try setarch i686 --uname-2.6 uname -a).
                – Gilles
                Jun 16 '14 at 13:20




                1




                1




                @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                – goldilocks
                Jun 16 '14 at 13:30






                @Gilles I've edited machine, nodename, and release into the question with a reference to the comments. Again, the question wasn't actually about all those fields.
                – goldilocks
                Jun 16 '14 at 13:30














                up vote
                23
                down vote













                The data is stored in init/version.c:



                struct uts_namespace init_uts_ns = {
                .kref = {
                .refcount = ATOMIC_INIT(2),
                },
                .name = {
                .sysname = UTS_SYSNAME,
                .nodename = UTS_NODENAME,
                .release = UTS_RELEASE,
                .version = UTS_VERSION,
                .machine = UTS_MACHINE,
                .domainname = UTS_DOMAINNAME,
                },
                .user_ns = &init_user_ns,
                .proc_inum = PROC_UTS_INIT_INO,
                };
                EXPORT_SYMBOL_GPL(init_uts_ns);


                The strings themselves are in include/generated/compile.h:



                #define UTS_MACHINE "x86_64"
                #define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"


                and in include/generated/utsrelease.h:



                #define UTS_RELEASE "3.14.0-v2-v"


                UTS_SYSNAME may be defined in include/linux/uts.h



                #ifndef UTS_SYSNAME
                #define UTS_SYSNAME "Linux"
                #endif


                or as a #define in makefiles



                Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:



                # hostname
                hell
                # unshare --uts /bin/bash
                # echo test > /proc/sys/kernel/hostname
                # hostname
                test
                # exit
                # hostname
                hell





                share|improve this answer























                • This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                  – Faheem Mitha
                  Jun 16 '14 at 18:12












                • +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                  – Tino
                  Jan 20 '17 at 11:39















                up vote
                23
                down vote













                The data is stored in init/version.c:



                struct uts_namespace init_uts_ns = {
                .kref = {
                .refcount = ATOMIC_INIT(2),
                },
                .name = {
                .sysname = UTS_SYSNAME,
                .nodename = UTS_NODENAME,
                .release = UTS_RELEASE,
                .version = UTS_VERSION,
                .machine = UTS_MACHINE,
                .domainname = UTS_DOMAINNAME,
                },
                .user_ns = &init_user_ns,
                .proc_inum = PROC_UTS_INIT_INO,
                };
                EXPORT_SYMBOL_GPL(init_uts_ns);


                The strings themselves are in include/generated/compile.h:



                #define UTS_MACHINE "x86_64"
                #define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"


                and in include/generated/utsrelease.h:



                #define UTS_RELEASE "3.14.0-v2-v"


                UTS_SYSNAME may be defined in include/linux/uts.h



                #ifndef UTS_SYSNAME
                #define UTS_SYSNAME "Linux"
                #endif


                or as a #define in makefiles



                Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:



                # hostname
                hell
                # unshare --uts /bin/bash
                # echo test > /proc/sys/kernel/hostname
                # hostname
                test
                # exit
                # hostname
                hell





                share|improve this answer























                • This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                  – Faheem Mitha
                  Jun 16 '14 at 18:12












                • +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                  – Tino
                  Jan 20 '17 at 11:39













                up vote
                23
                down vote










                up vote
                23
                down vote









                The data is stored in init/version.c:



                struct uts_namespace init_uts_ns = {
                .kref = {
                .refcount = ATOMIC_INIT(2),
                },
                .name = {
                .sysname = UTS_SYSNAME,
                .nodename = UTS_NODENAME,
                .release = UTS_RELEASE,
                .version = UTS_VERSION,
                .machine = UTS_MACHINE,
                .domainname = UTS_DOMAINNAME,
                },
                .user_ns = &init_user_ns,
                .proc_inum = PROC_UTS_INIT_INO,
                };
                EXPORT_SYMBOL_GPL(init_uts_ns);


                The strings themselves are in include/generated/compile.h:



                #define UTS_MACHINE "x86_64"
                #define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"


                and in include/generated/utsrelease.h:



                #define UTS_RELEASE "3.14.0-v2-v"


                UTS_SYSNAME may be defined in include/linux/uts.h



                #ifndef UTS_SYSNAME
                #define UTS_SYSNAME "Linux"
                #endif


                or as a #define in makefiles



                Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:



                # hostname
                hell
                # unshare --uts /bin/bash
                # echo test > /proc/sys/kernel/hostname
                # hostname
                test
                # exit
                # hostname
                hell





                share|improve this answer














                The data is stored in init/version.c:



                struct uts_namespace init_uts_ns = {
                .kref = {
                .refcount = ATOMIC_INIT(2),
                },
                .name = {
                .sysname = UTS_SYSNAME,
                .nodename = UTS_NODENAME,
                .release = UTS_RELEASE,
                .version = UTS_VERSION,
                .machine = UTS_MACHINE,
                .domainname = UTS_DOMAINNAME,
                },
                .user_ns = &init_user_ns,
                .proc_inum = PROC_UTS_INIT_INO,
                };
                EXPORT_SYMBOL_GPL(init_uts_ns);


                The strings themselves are in include/generated/compile.h:



                #define UTS_MACHINE "x86_64"
                #define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"


                and in include/generated/utsrelease.h:



                #define UTS_RELEASE "3.14.0-v2-v"


                UTS_SYSNAME may be defined in include/linux/uts.h



                #ifndef UTS_SYSNAME
                #define UTS_SYSNAME "Linux"
                #endif


                or as a #define in makefiles



                Finally, the hostname and domainname can be controlled by /proc/sys/kernel/{hostname,domainname}. These are per UTS namespace:



                # hostname
                hell
                # unshare --uts /bin/bash
                # echo test > /proc/sys/kernel/hostname
                # hostname
                test
                # exit
                # hostname
                hell






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jun 16 '14 at 18:10









                Faheem Mitha

                22.6k1879134




                22.6k1879134










                answered Jun 14 '14 at 0:03









                V13

                2,644613




                2,644613












                • This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                  – Faheem Mitha
                  Jun 16 '14 at 18:12












                • +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                  – Tino
                  Jan 20 '17 at 11:39


















                • This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                  – Faheem Mitha
                  Jun 16 '14 at 18:12












                • +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                  – Tino
                  Jan 20 '17 at 11:39
















                This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                – Faheem Mitha
                Jun 16 '14 at 18:12






                This is generally a good and complete answer, but it may be worth while answering the poster's question directl. I believe this would amount to - change the relevant entry in the relevant file and recompile. You wrote "or as a #define in makefiles". Can you elaborate?
                – Faheem Mitha
                Jun 16 '14 at 18:12














                +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                – Tino
                Jan 20 '17 at 11:39




                +1 for unshare. Somehow I managed to miss this command until today. Thanks!
                – Tino
                Jan 20 '17 at 11:39










                up vote
                8
                down vote













                With the help of a Linux Cross Reference and your mention of /proc/sys/kernel/ostype, I tracked ostype to include/linux/sysctl.h,
                where a comment says that names are added by calling register_sysctl_table.



                So where is that called from? One place is kernel/utsname_sysctl.c, which includes include/linux/uts.h, where we find:




                /*
                * Defines for what uname() should return
                */
                #ifndef UTS_SYSNAME
                #define UTS_SYSNAME "Linux"
                #endif



                So, as the kernel documentation states:




                The only way to tune these values is to rebuild the kernel




                :-)






                share|improve this answer



























                  up vote
                  8
                  down vote













                  With the help of a Linux Cross Reference and your mention of /proc/sys/kernel/ostype, I tracked ostype to include/linux/sysctl.h,
                  where a comment says that names are added by calling register_sysctl_table.



                  So where is that called from? One place is kernel/utsname_sysctl.c, which includes include/linux/uts.h, where we find:




                  /*
                  * Defines for what uname() should return
                  */
                  #ifndef UTS_SYSNAME
                  #define UTS_SYSNAME "Linux"
                  #endif



                  So, as the kernel documentation states:




                  The only way to tune these values is to rebuild the kernel




                  :-)






                  share|improve this answer

























                    up vote
                    8
                    down vote










                    up vote
                    8
                    down vote









                    With the help of a Linux Cross Reference and your mention of /proc/sys/kernel/ostype, I tracked ostype to include/linux/sysctl.h,
                    where a comment says that names are added by calling register_sysctl_table.



                    So where is that called from? One place is kernel/utsname_sysctl.c, which includes include/linux/uts.h, where we find:




                    /*
                    * Defines for what uname() should return
                    */
                    #ifndef UTS_SYSNAME
                    #define UTS_SYSNAME "Linux"
                    #endif



                    So, as the kernel documentation states:




                    The only way to tune these values is to rebuild the kernel




                    :-)






                    share|improve this answer














                    With the help of a Linux Cross Reference and your mention of /proc/sys/kernel/ostype, I tracked ostype to include/linux/sysctl.h,
                    where a comment says that names are added by calling register_sysctl_table.



                    So where is that called from? One place is kernel/utsname_sysctl.c, which includes include/linux/uts.h, where we find:




                    /*
                    * Defines for what uname() should return
                    */
                    #ifndef UTS_SYSNAME
                    #define UTS_SYSNAME "Linux"
                    #endif



                    So, as the kernel documentation states:




                    The only way to tune these values is to rebuild the kernel




                    :-)







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 26 at 0:01









                    Isaac

                    10.2k11445




                    10.2k11445










                    answered Jun 13 '14 at 22:47









                    deltab

                    36319




                    36319






















                        up vote
                        5
                        down vote













                        As commented elsewhere, the information come with the uname syscall, which information is hard-coded in the running kernel.



                        The version part is normally set when compiling a new kernel by the Makefile:



                        VERSION = 3
                        PATCHLEVEL = 15
                        SUBLEVEL = 0
                        EXTRAVERSION =


                        when I had time to play compiling my kernels, I used to add things over there in EXTRAVERSION; that gave you uname -r with things like 3.4.1-mytestkernel.



                        I do not fully understand it, but I think that the rest of the information is setup in the Makefile also around line 944:



                        # ---------------------------------------------------------------------------

                        # KERNELRELEASE can change from a few different places, meaning version.h
                        # needs to be updated, so this check is forced on all builds

                        uts_len := 64
                        define filechk_utsrelease.h
                        if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then
                        echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;
                        exit 1;
                        fi;
                        (echo #define UTS_RELEASE "$(KERNELRELEASE)";)
                        endef

                        define filechk_version.h
                        (echo #define LINUX_VERSION_CODE $(shell
                        expr $(VERSION) * 65536 + 0$(PATCHLEVEL) * 256 + 0$(SUBLEVEL));
                        echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
                        endef

                        $(version_h): $(srctree)/Makefile FORCE
                        $(call filechk,version.h)

                        include/generated/utsrelease.h: include/config/kernel.release FORCE
                        $(call filechk,utsrelease.h)

                        PHONY += headerdep
                        headerdep:
                        $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1
                        $(srctree)/scripts/headerdep.pl -I$(srctree)/include


                        For the rest of the data, the sys_uname syscall is generated using macros (in a quite convoluted way), you can start from here if you feel adventurous.



                        Probably the best way to change such information is writing a kernel module to override the uname syscall; I never did that but you can find info in this page at section 4.2 (sorry, no direct link). Notice however that that code is referring to a quite old kernel (now Linux kernel has uts namespaces, whatever they mean) so you will need to change it probably a lot.






                        share|improve this answer























                        • Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                          – user237251
                          Jun 13 '14 at 17:48










                        • @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                          – JAB
                          Jun 13 '14 at 17:55












                        • @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                          – user237251
                          Jun 17 '14 at 17:14

















                        up vote
                        5
                        down vote













                        As commented elsewhere, the information come with the uname syscall, which information is hard-coded in the running kernel.



                        The version part is normally set when compiling a new kernel by the Makefile:



                        VERSION = 3
                        PATCHLEVEL = 15
                        SUBLEVEL = 0
                        EXTRAVERSION =


                        when I had time to play compiling my kernels, I used to add things over there in EXTRAVERSION; that gave you uname -r with things like 3.4.1-mytestkernel.



                        I do not fully understand it, but I think that the rest of the information is setup in the Makefile also around line 944:



                        # ---------------------------------------------------------------------------

                        # KERNELRELEASE can change from a few different places, meaning version.h
                        # needs to be updated, so this check is forced on all builds

                        uts_len := 64
                        define filechk_utsrelease.h
                        if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then
                        echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;
                        exit 1;
                        fi;
                        (echo #define UTS_RELEASE "$(KERNELRELEASE)";)
                        endef

                        define filechk_version.h
                        (echo #define LINUX_VERSION_CODE $(shell
                        expr $(VERSION) * 65536 + 0$(PATCHLEVEL) * 256 + 0$(SUBLEVEL));
                        echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
                        endef

                        $(version_h): $(srctree)/Makefile FORCE
                        $(call filechk,version.h)

                        include/generated/utsrelease.h: include/config/kernel.release FORCE
                        $(call filechk,utsrelease.h)

                        PHONY += headerdep
                        headerdep:
                        $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1
                        $(srctree)/scripts/headerdep.pl -I$(srctree)/include


                        For the rest of the data, the sys_uname syscall is generated using macros (in a quite convoluted way), you can start from here if you feel adventurous.



                        Probably the best way to change such information is writing a kernel module to override the uname syscall; I never did that but you can find info in this page at section 4.2 (sorry, no direct link). Notice however that that code is referring to a quite old kernel (now Linux kernel has uts namespaces, whatever they mean) so you will need to change it probably a lot.






                        share|improve this answer























                        • Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                          – user237251
                          Jun 13 '14 at 17:48










                        • @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                          – JAB
                          Jun 13 '14 at 17:55












                        • @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                          – user237251
                          Jun 17 '14 at 17:14















                        up vote
                        5
                        down vote










                        up vote
                        5
                        down vote









                        As commented elsewhere, the information come with the uname syscall, which information is hard-coded in the running kernel.



                        The version part is normally set when compiling a new kernel by the Makefile:



                        VERSION = 3
                        PATCHLEVEL = 15
                        SUBLEVEL = 0
                        EXTRAVERSION =


                        when I had time to play compiling my kernels, I used to add things over there in EXTRAVERSION; that gave you uname -r with things like 3.4.1-mytestkernel.



                        I do not fully understand it, but I think that the rest of the information is setup in the Makefile also around line 944:



                        # ---------------------------------------------------------------------------

                        # KERNELRELEASE can change from a few different places, meaning version.h
                        # needs to be updated, so this check is forced on all builds

                        uts_len := 64
                        define filechk_utsrelease.h
                        if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then
                        echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;
                        exit 1;
                        fi;
                        (echo #define UTS_RELEASE "$(KERNELRELEASE)";)
                        endef

                        define filechk_version.h
                        (echo #define LINUX_VERSION_CODE $(shell
                        expr $(VERSION) * 65536 + 0$(PATCHLEVEL) * 256 + 0$(SUBLEVEL));
                        echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
                        endef

                        $(version_h): $(srctree)/Makefile FORCE
                        $(call filechk,version.h)

                        include/generated/utsrelease.h: include/config/kernel.release FORCE
                        $(call filechk,utsrelease.h)

                        PHONY += headerdep
                        headerdep:
                        $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1
                        $(srctree)/scripts/headerdep.pl -I$(srctree)/include


                        For the rest of the data, the sys_uname syscall is generated using macros (in a quite convoluted way), you can start from here if you feel adventurous.



                        Probably the best way to change such information is writing a kernel module to override the uname syscall; I never did that but you can find info in this page at section 4.2 (sorry, no direct link). Notice however that that code is referring to a quite old kernel (now Linux kernel has uts namespaces, whatever they mean) so you will need to change it probably a lot.






                        share|improve this answer














                        As commented elsewhere, the information come with the uname syscall, which information is hard-coded in the running kernel.



                        The version part is normally set when compiling a new kernel by the Makefile:



                        VERSION = 3
                        PATCHLEVEL = 15
                        SUBLEVEL = 0
                        EXTRAVERSION =


                        when I had time to play compiling my kernels, I used to add things over there in EXTRAVERSION; that gave you uname -r with things like 3.4.1-mytestkernel.



                        I do not fully understand it, but I think that the rest of the information is setup in the Makefile also around line 944:



                        # ---------------------------------------------------------------------------

                        # KERNELRELEASE can change from a few different places, meaning version.h
                        # needs to be updated, so this check is forced on all builds

                        uts_len := 64
                        define filechk_utsrelease.h
                        if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then
                        echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2;
                        exit 1;
                        fi;
                        (echo #define UTS_RELEASE "$(KERNELRELEASE)";)
                        endef

                        define filechk_version.h
                        (echo #define LINUX_VERSION_CODE $(shell
                        expr $(VERSION) * 65536 + 0$(PATCHLEVEL) * 256 + 0$(SUBLEVEL));
                        echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
                        endef

                        $(version_h): $(srctree)/Makefile FORCE
                        $(call filechk,version.h)

                        include/generated/utsrelease.h: include/config/kernel.release FORCE
                        $(call filechk,utsrelease.h)

                        PHONY += headerdep
                        headerdep:
                        $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1
                        $(srctree)/scripts/headerdep.pl -I$(srctree)/include


                        For the rest of the data, the sys_uname syscall is generated using macros (in a quite convoluted way), you can start from here if you feel adventurous.



                        Probably the best way to change such information is writing a kernel module to override the uname syscall; I never did that but you can find info in this page at section 4.2 (sorry, no direct link). Notice however that that code is referring to a quite old kernel (now Linux kernel has uts namespaces, whatever they mean) so you will need to change it probably a lot.







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited May 23 '17 at 12:39









                        Community

                        1




                        1










                        answered Jun 13 '14 at 17:19









                        Rmano

                        1,87611328




                        1,87611328












                        • Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                          – user237251
                          Jun 13 '14 at 17:48










                        • @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                          – JAB
                          Jun 13 '14 at 17:55












                        • @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                          – user237251
                          Jun 17 '14 at 17:14




















                        • Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                          – user237251
                          Jun 13 '14 at 17:48










                        • @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                          – JAB
                          Jun 13 '14 at 17:55












                        • @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                          – user237251
                          Jun 17 '14 at 17:14


















                        Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                        – user237251
                        Jun 13 '14 at 17:48




                        Thanks, everyone. I already knew it had something to do with uname. However, what I can't fathom is how and where inside the source the string "Linux" is defined. All I know is where I can find that information during runtime (it's contained inside /proc/sys/kernel/ostype). Finding out how exactly the kernel itself knows it's proper name would be one of the more interesting things, I'd say.
                        – user237251
                        Jun 13 '14 at 17:48












                        @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                        – JAB
                        Jun 13 '14 at 17:55






                        @user237251 how many instances of the word "Linux" occur in the kernel source in string contexts? If it's not that many, you could just examine the results of a textual search and see where that leads you.
                        – JAB
                        Jun 13 '14 at 17:55














                        @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                        – user237251
                        Jun 17 '14 at 17:14






                        @JAB Way too many. Fortunately, someone on kernelnewbies.org helped me solve the "mystery". Linux gets its sys name from /include/Linux/uts.h. See here: lxr.free-electrons.com/source/include/linux/uts.h?v=3.10
                        – user237251
                        Jun 17 '14 at 17:14












                        up vote
                        2
                        down vote













                        While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.



                        man 2 uname



                        should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.



                        You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.






                        share|improve this answer

















                        • 3




                          If you do strace uname, it will confirm that the uname system call is used.
                          – Graeme
                          Jun 13 '14 at 14:11















                        up vote
                        2
                        down vote













                        While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.



                        man 2 uname



                        should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.



                        You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.






                        share|improve this answer

















                        • 3




                          If you do strace uname, it will confirm that the uname system call is used.
                          – Graeme
                          Jun 13 '14 at 14:11













                        up vote
                        2
                        down vote










                        up vote
                        2
                        down vote









                        While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.



                        man 2 uname



                        should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.



                        You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.






                        share|improve this answer












                        While I couldn't find anything in the source to indicate this, I believe it uses the uname syscall.



                        man 2 uname



                        should tell you more about it. If that's the case it's getting the information directly from the kernel and changing it would probably require recompilation.



                        You could change the binary for you uname to do whatever you want though, just write over it with w/e program you please. The downside being some scripts rely on that output.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Jun 13 '14 at 14:08









                        Livinglifeback

                        1,094713




                        1,094713








                        • 3




                          If you do strace uname, it will confirm that the uname system call is used.
                          – Graeme
                          Jun 13 '14 at 14:11














                        • 3




                          If you do strace uname, it will confirm that the uname system call is used.
                          – Graeme
                          Jun 13 '14 at 14:11








                        3




                        3




                        If you do strace uname, it will confirm that the uname system call is used.
                        – Graeme
                        Jun 13 '14 at 14:11




                        If you do strace uname, it will confirm that the uname system call is used.
                        – Graeme
                        Jun 13 '14 at 14:11










                        up vote
                        1
                        down vote













                        Proper way to change uname would be to change compile headers and re-compile like others suggested. But I am not sure why you would want to go through that much trouble when you can do something like,



                        alias uname 'uname \!* | sed s/2.6.13/2.6.52/'


                        or even



                        alias uname 'echo whatever'





                        share|improve this answer



























                          up vote
                          1
                          down vote













                          Proper way to change uname would be to change compile headers and re-compile like others suggested. But I am not sure why you would want to go through that much trouble when you can do something like,



                          alias uname 'uname \!* | sed s/2.6.13/2.6.52/'


                          or even



                          alias uname 'echo whatever'





                          share|improve this answer

























                            up vote
                            1
                            down vote










                            up vote
                            1
                            down vote









                            Proper way to change uname would be to change compile headers and re-compile like others suggested. But I am not sure why you would want to go through that much trouble when you can do something like,



                            alias uname 'uname \!* | sed s/2.6.13/2.6.52/'


                            or even



                            alias uname 'echo whatever'





                            share|improve this answer














                            Proper way to change uname would be to change compile headers and re-compile like others suggested. But I am not sure why you would want to go through that much trouble when you can do something like,



                            alias uname 'uname \!* | sed s/2.6.13/2.6.52/'


                            or even



                            alias uname 'echo whatever'






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jan 26 '17 at 20:35









                            sam

                            13.2k31426




                            13.2k31426










                            answered Jan 26 '17 at 20:16









                            Saurabh

                            111




                            111






















                                up vote
                                0
                                down vote













                                Rmano's answer got me partway, but the real magic is easier discovered by passing the Q= option in your make commandline in the kernel source directory. it lets you see the details, one of which is a call to a script: echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)". executing that same snippet gives the kernel release number, 4.4.19-00010-ge5dddbf. if you look at the script, it determines the number from the versioning system, and running it with bash -x shows the exact process:



                                +++ git rev-parse --verify --short HEAD
                                ++ head=e5dddbf
                                +++ git describe --exact-match
                                ++ '[' -z '' ']'
                                ++ false
                                +++ git describe
                                ++ atag=release/A530_os_1.0.0-10-ge5dddbf
                                ++ echo release/A530_os_1.0.0-10-ge5dddbf
                                ++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
                                ++ git config --get svn-remote.svn.url
                                ++ git diff-index --name-only HEAD
                                ++ grep -qv '^scripts/package'
                                ++ return
                                + res=-00010-ge5dddbf
                                + echo -00010-ge5dddbf
                                -00010-ge5dddbf


                                what this shows me is that if I want to build a kernel module to work with my running kernel, I'm on the wrong tagged release and the wrong commit. I need to fix that, and build at least the DTBs (make dtbs) in order to create the generated files with the right version number.





                                turns out, even that wasn't enough. I had to replace scripts/setlocalversion to one that simply does:



                                #!/bin/sh
                                echo -0710GC0F-44F-01QA


                                then rebuild the autogenerated files:



                                make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs


                                then I could build Derek Molloy's sample driver and was able to insmod it successfully. apparently the warning about Module.symvers not being present didn't matter. all Linux was using to determine if the module would work was that localversion string.






                                share|improve this answer



























                                  up vote
                                  0
                                  down vote













                                  Rmano's answer got me partway, but the real magic is easier discovered by passing the Q= option in your make commandline in the kernel source directory. it lets you see the details, one of which is a call to a script: echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)". executing that same snippet gives the kernel release number, 4.4.19-00010-ge5dddbf. if you look at the script, it determines the number from the versioning system, and running it with bash -x shows the exact process:



                                  +++ git rev-parse --verify --short HEAD
                                  ++ head=e5dddbf
                                  +++ git describe --exact-match
                                  ++ '[' -z '' ']'
                                  ++ false
                                  +++ git describe
                                  ++ atag=release/A530_os_1.0.0-10-ge5dddbf
                                  ++ echo release/A530_os_1.0.0-10-ge5dddbf
                                  ++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
                                  ++ git config --get svn-remote.svn.url
                                  ++ git diff-index --name-only HEAD
                                  ++ grep -qv '^scripts/package'
                                  ++ return
                                  + res=-00010-ge5dddbf
                                  + echo -00010-ge5dddbf
                                  -00010-ge5dddbf


                                  what this shows me is that if I want to build a kernel module to work with my running kernel, I'm on the wrong tagged release and the wrong commit. I need to fix that, and build at least the DTBs (make dtbs) in order to create the generated files with the right version number.





                                  turns out, even that wasn't enough. I had to replace scripts/setlocalversion to one that simply does:



                                  #!/bin/sh
                                  echo -0710GC0F-44F-01QA


                                  then rebuild the autogenerated files:



                                  make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs


                                  then I could build Derek Molloy's sample driver and was able to insmod it successfully. apparently the warning about Module.symvers not being present didn't matter. all Linux was using to determine if the module would work was that localversion string.






                                  share|improve this answer

























                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    Rmano's answer got me partway, but the real magic is easier discovered by passing the Q= option in your make commandline in the kernel source directory. it lets you see the details, one of which is a call to a script: echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)". executing that same snippet gives the kernel release number, 4.4.19-00010-ge5dddbf. if you look at the script, it determines the number from the versioning system, and running it with bash -x shows the exact process:



                                    +++ git rev-parse --verify --short HEAD
                                    ++ head=e5dddbf
                                    +++ git describe --exact-match
                                    ++ '[' -z '' ']'
                                    ++ false
                                    +++ git describe
                                    ++ atag=release/A530_os_1.0.0-10-ge5dddbf
                                    ++ echo release/A530_os_1.0.0-10-ge5dddbf
                                    ++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
                                    ++ git config --get svn-remote.svn.url
                                    ++ git diff-index --name-only HEAD
                                    ++ grep -qv '^scripts/package'
                                    ++ return
                                    + res=-00010-ge5dddbf
                                    + echo -00010-ge5dddbf
                                    -00010-ge5dddbf


                                    what this shows me is that if I want to build a kernel module to work with my running kernel, I'm on the wrong tagged release and the wrong commit. I need to fix that, and build at least the DTBs (make dtbs) in order to create the generated files with the right version number.





                                    turns out, even that wasn't enough. I had to replace scripts/setlocalversion to one that simply does:



                                    #!/bin/sh
                                    echo -0710GC0F-44F-01QA


                                    then rebuild the autogenerated files:



                                    make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs


                                    then I could build Derek Molloy's sample driver and was able to insmod it successfully. apparently the warning about Module.symvers not being present didn't matter. all Linux was using to determine if the module would work was that localversion string.






                                    share|improve this answer














                                    Rmano's answer got me partway, but the real magic is easier discovered by passing the Q= option in your make commandline in the kernel source directory. it lets you see the details, one of which is a call to a script: echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)". executing that same snippet gives the kernel release number, 4.4.19-00010-ge5dddbf. if you look at the script, it determines the number from the versioning system, and running it with bash -x shows the exact process:



                                    +++ git rev-parse --verify --short HEAD
                                    ++ head=e5dddbf
                                    +++ git describe --exact-match
                                    ++ '[' -z '' ']'
                                    ++ false
                                    +++ git describe
                                    ++ atag=release/A530_os_1.0.0-10-ge5dddbf
                                    ++ echo release/A530_os_1.0.0-10-ge5dddbf
                                    ++ awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
                                    ++ git config --get svn-remote.svn.url
                                    ++ git diff-index --name-only HEAD
                                    ++ grep -qv '^scripts/package'
                                    ++ return
                                    + res=-00010-ge5dddbf
                                    + echo -00010-ge5dddbf
                                    -00010-ge5dddbf


                                    what this shows me is that if I want to build a kernel module to work with my running kernel, I'm on the wrong tagged release and the wrong commit. I need to fix that, and build at least the DTBs (make dtbs) in order to create the generated files with the right version number.





                                    turns out, even that wasn't enough. I had to replace scripts/setlocalversion to one that simply does:



                                    #!/bin/sh
                                    echo -0710GC0F-44F-01QA


                                    then rebuild the autogenerated files:



                                    make Q= ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs


                                    then I could build Derek Molloy's sample driver and was able to insmod it successfully. apparently the warning about Module.symvers not being present didn't matter. all Linux was using to determine if the module would work was that localversion string.







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Jul 16 '17 at 1:05

























                                    answered Jul 16 '17 at 0:06









                                    jcomeau_ictx

                                    1907




                                    1907






























                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.





                                        Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                        Please pay close attention to the following guidance:


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f136959%2fwhere-does-uname-get-its-information-from%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Morgemoulin

                                        Scott Moir

                                        Souastre