鱼C论坛

 找回密码
 立即注册
查看: 28|回复: 1

[技术交流] 一份古老的C代码

[复制链接]
发表于 2026-5-11 19:35:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
chdir  /usr/sys/ken

  1. # cat main.c
  2. #
  3. #include "../param.h"
  4. #include "../user.h"
  5. #include "../systm.h"
  6. #include "../proc.h"
  7. #include "../text.h"
  8. #include "../inode.h"
  9. #include "../seg.h"

  10. #define CLOCK1  0177546
  11. #define CLOCK2  0172540
  12. /*
  13. * Icode is the octal bootstrap
  14. * program executed in user mode
  15. * to bring up the system.
  16. */
  17. int     icode[]
  18. {
  19.         0104413,        /* sys exec; init; initp */
  20.         0000014,
  21.         0000010,
  22.         0000777,        /* br . */
  23.         0000014,        /* initp: init; 0 */
  24.         0000000,
  25.         0062457,        /* init: </etc/init\0> */
  26.         0061564,
  27.         0064457,
  28.         0064556,
  29.         0000164,
  30. };

  31. /*
  32. * Initialization code.
  33. * Called from m40.s or m45.s as
  34. * soon as a stack and segmentation
  35. * have been established.
  36. * Functions:
  37. *      clear and free user core
  38. *      find which clock is configured
  39. *      hand craft 0th process
  40. *      call all initialization routines
  41. *      fork - process 0 to schedule
  42. *           - process 1 execute bootstrap
  43. *
  44. * panic: no clock -- neither clock responds
  45. * loop at loc 6 in user mode -- /etc/init
  46. *      cannot be executed.
  47. */
  48. main()
  49. {
  50.         extern schar;
  51.         register i, *p;

  52.         /*
  53.          * zero and free all of core
  54.          */

  55.         updlock = 0;
  56.         i = *ka6 + USIZE;
  57.         UISD->r[0] = 077406;
  58.         for(;;) {
  59.                 UISA->r[0] = i;
  60.                 if(fuibyte(0) < 0)
  61.                         break;
  62.                 clearseg(i);
  63.                 maxmem++;
  64.                 mfree(coremap, 1, i);
  65.                 i++;
  66.         }
  67.         if(cputype == 70)
  68.         for(i=0; i<62; i=+2) {
  69.                 UBMAP->r[i] = i<<12;
  70.                 UBMAP->r[i+1] = 0;
  71.         }
  72.         printf("mem = %l\n", maxmem*5/16);
  73.         printf("RESTRICTED RIGHTS\n\n");
  74.         printf("Use, duplication or disclosure is subject to\n");
  75.         printf("restrictions stated in Contract with Western\n");
  76.         printf("Electric Company, Inc.\n");

  77.         maxmem = min(maxmem, MAXMEM);
  78.         mfree(swapmap, nswap, swplo);

  79.         /*
  80.          * determine clock
  81.          */

  82.         UISA->r[7] = ka6[1]; /* io segment */
  83.         UISD->r[7] = 077406;
  84.         lks = CLOCK1;
  85.         if(fuiword(lks) == -1) {
  86.                 lks = CLOCK2;
  87.                 if(fuiword(lks) == -1)
  88.                         panic("no clock");
  89.         }

  90.         /*
  91.          * set up system process
  92.          */

  93.         proc[0].p_addr = *ka6;
  94.         proc[0].p_size = USIZE;
  95.         proc[0].p_stat = SRUN;
  96.         proc[0].p_flag =| SLOAD|SSYS;
  97.         u.u_procp = &proc[0];

  98.         /*
  99.          * set up 'known' i-nodes
  100.          */

  101.         *lks = 0115;
  102.         cinit();
  103.         binit();
  104.         iinit();
  105.         rootdir = iget(rootdev, ROOTINO);
  106.         rootdir->i_flag =& ~ILOCK;
  107.         u.u_cdir = iget(rootdev, ROOTINO);
  108.         u.u_cdir->i_flag =& ~ILOCK;

  109.         /*
  110.          * make init process
  111.          * enter scheduling loop
  112.          * with system process
  113.          */

  114.         if(newproc()) {
  115.                 expand(USIZE+1);
  116.                 estabur(0, 1, 0, 0);
  117.                 copyout(icode, 0, sizeof icode);
  118.                 /*
  119.                  * Return goes to loc. 0 of user init
  120.                  * code just copied out.
  121.                  */
  122.                 return;
  123.         }
  124.         sched();
  125. }

  126. /*
  127. * Load the user hardware segmentation
  128. * registers from the software prototype.
  129. * The software registers must have
  130. * been setup prior by estabur.
  131. */
  132. sureg()
  133. {
  134.         register *up, *rp, a;

  135.         a = u.u_procp->p_addr;
  136.         up = &u.u_uisa[16];
  137.         rp = &UISA->r[16];
  138.         if(cputype == 40) {
  139.                 up =- 8;
  140.                 rp =- 8;
  141.         }
  142.         while(rp > &UISA->r[0])
  143.                 *--rp = *--up + a;
  144.         if((up=u.u_procp->p_textp) != NULL)
  145.                 a =- up->x_caddr;
  146.         up = &u.u_uisd[16];
  147.         rp = &UISD->r[16];
  148.         if(cputype == 40) {
  149.                 up =- 8;
  150.                 rp =- 8;
  151.         }
  152.         while(rp > &UISD->r[0]) {
  153.                 *--rp = *--up;
  154.                 if((*rp & WO) == 0)
  155.                         rp[(UISA-UISD)/2] =- a;
  156.         }
  157. }

  158. /*
  159. * Set up software prototype segmentation
  160. * registers to implement the 3 pseudo
  161. * text,data,stack segment sizes passed
  162. * as arguments.
  163. * The argument sep specifies if the
  164. * text and data+stack segments are to
  165. * be separated.
  166. */
  167. estabur(nt, nd, ns, sep)
  168. {
  169.         register a, *ap, *dp;

  170.         if(sep) {
  171.                 if(cputype == 40)
  172.                         goto err;
  173.                 if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8)
  174.                         goto err;
  175.         } else
  176.                 if(nseg(nt)+nseg(nd)+nseg(ns) > 8)
  177.                         goto err;
  178.         if(nt+nd+ns+USIZE > maxmem)
  179.                 goto err;
  180.         a = 0;
  181.         ap = &u.u_uisa[0];
  182.         dp = &u.u_uisd[0];
  183.         while(nt >= 128) {
  184.                 *dp++ = (127<<8) | RO;
  185.                 *ap++ = a;
  186.                 a =+ 128;
  187.                 nt =- 128;
  188.         }
  189.         if(nt) {
  190.                 *dp++ = ((nt-1)<<8) | RO;
  191.                 *ap++ = a;
  192.         }
  193.         if(sep)
  194.         while(ap < &u.u_uisa[8]) {
  195.                 *ap++ = 0;
  196.                 *dp++ = 0;
  197.         }
  198.         a = USIZE;
  199.         while(nd >= 128) {
  200.                 *dp++ = (127<<8) | RW;
  201.                 *ap++ = a;
  202.                 a =+ 128;
  203.                 nd =- 128;
  204.         }
  205.         if(nd) {
  206.                 *dp++ = ((nd-1)<<8) | RW;
  207.                 *ap++ = a;
  208.                 a =+ nd;
  209.         }
  210.         while(ap < &u.u_uisa[8]) {
  211.                 *dp++ = 0;
  212.                 *ap++ = 0;
  213.         }
  214.         if(sep)
  215.         while(ap < &u.u_uisa[16]) {
  216.                 *dp++ = 0;
  217.                 *ap++ = 0;
  218.         }
  219.         a =+ ns;
  220.         while(ns >= 128) {
  221.                 a =- 128;
  222.                 ns =- 128;
  223.                 *--dp = (127<<8) | RW;
  224.                 *--ap = a;
  225.         }
  226.         if(ns) {
  227.                 *--dp = ((128-ns)<<8) | RW | ED;
  228.                 *--ap = a-128;
  229.         }
  230.         if(!sep) {
  231.                 ap = &u.u_uisa[0];
  232.                 dp = &u.u_uisa[8];
  233.                 while(ap < &u.u_uisa[8])
  234.                         *dp++ = *ap++;
  235.                 ap = &u.u_uisd[0];
  236.                 dp = &u.u_uisd[8];
  237.                 while(ap < &u.u_uisd[8])
  238.                         *dp++ = *ap++;
  239.         }
  240.         sureg();
  241.         return(0);

  242. err:
  243.         u.u_error = ENOMEM;
  244.         return(-1);
  245. }

  246. /*
  247. * Return the arg/128 rounded up.
  248. */
  249. nseg(n)
  250. {

  251.         return((n+127)>>7);
  252. }
  253. #
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-5-11 19:35:30 | 显示全部楼层
这是一份非常经典的 Unix V6 内核(大约 1975 年)的 main.c 文件,来自贝尔实验室。它负责计算机启动后 第一个用户态进程的创建 和系统初始化。下面用通俗的方式解释核心逻辑:

  • 清除用户核心:循环扫描所有未被内核占用的内存页,用 clearseg 清零,并调用 mfree 归还给空闲内存管理表(coremap)。
  • 检测时钟:检查两个可能的时钟地址(CLOCK1CLOCK2),如果都失败则调用 panic("no clock")
  • 建立 0 号进程(系统进程):手动设置 proc 结构,赋予 SRUN(就绪)状态和 SSYS(系统进程)标志。
  • 初始化文件系统:调用 cinit()(字符设备)、binit()(块设备)、iinit()(i 节点缓存),然后通过 iget 获取根目录(rootdir)。
  • 创建 init 进程(1 号进程):调用 newproc() 复制进程,如果成功(返回非零),则扩展用户空间、设置用户段寄存器、将 icode 引导程序复制到进程地址 0 处,然后 return 会跳转到该引导程序,最终执行 /etc/init
  • 调度循环:如果创建失败,则父进程(0 号进程)进入 sched() 循环,作为系统调度器永远运行。


  1. int icode { ... }
复制代码
是一个硬编码的引导代码(八进制),它执行 exec("/etc/init") 来启动用户态的管理进程。整个流程就是操作系统从硬件启动到多任务运行的 关键桥梁

如果你对其中某个细节(如内存分段、时钟检测)有疑问,欢迎继续提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-5-24 16:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表