📄 main.c
字号:
/**************************************************************************NETBOOT - BOOTP/TFTP Bootstrap ProgramAuthor: Martin Renters Date: Dec/93**************************************************************************//* #define MDEBUG */#include "netboot.h"int jmp_bootmenu[10];struct exec head;char *loadpoint;char *kernel;char kernel_buf[128];void (*kernelentry)();struct nfs_diskless nfsdiskless;int hostnamelen;char config_buffer[512]; /* Max TFTP packet */struct bootinfo bootinfo;int root_nfs_port;unsigned long netmask;char kernel_handle[32];int offset, howto;extern char eth_driver[];extern char packet[];extern int packetlen, rpc_id;char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };/**************************************************************************MAIN - Kick off routine**************************************************************************/main(){ int c; extern char edata[], end[]; bzero(edata,end-edata); /* Zero BSS */#ifdef ASK_BOOT while (1) { printf("\nBoot from Network (Y/N) ? "); c = getchar(); if ((c >= 'a') && (c <= 'z')) c &= 0x5F; if (c == '\r') break; putchar(c); if (c == 'N') exit(0); if (c == 'Y') break; printf(" - bad response\n\r"); }#endif /* get the bios's idea about the disks geometry */ for(c = 0; c < N_BIOS_GEOM; c ++) bootinfo.bi_bios_geom[c] = get_diskinfo(c + 0x80); gateA20(); printf("\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n" "\nSearching for adapter..."); if (!eth_probe()) { printf("No adapter found.\n"); exit(0); } kernel = DEFAULT_BOOTFILE; while (1) { if (setjmp(jmp_bootmenu)) bootmenu(); else load(); }}voidnfsload(length){ int err, read_size; while (length > 0) { read_size = length > NFS_READ_SIZE ? NFS_READ_SIZE : length; if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, offset, read_size, loadpoint)) != read_size) { if (err < 0) { printf("Unable to read data: "); nfs_err(err); } longjmp(jmp_bootmenu, 1); } loadpoint += err; length -= err; offset += err; }}/**************************************************************************LOAD - Try to get booted**************************************************************************/load(){ char *p,*q; char cfg[64]; int root_mount_port; int swap_nfs_port; int swap_mount_port; char cmd_line[80]; int err, read_size, i; long addr, broadcast; int swsize; unsigned long pad; config_buffer[0]='\0'; /* clear; bootp might fill this up *//* Initialize this early on */ nfsdiskless.root_args.rsize = 8192; nfsdiskless.root_args.wsize = 8192; nfsdiskless.swap_args.rsize = 8192; nfsdiskless.swap_args.wsize = 8192; nfsdiskless.root_args.sotype = SOCK_DGRAM; nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); nfsdiskless.swap_args.sotype = SOCK_DGRAM; nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); /* Find a server to get BOOTP reply from */ if (!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr) { printf("\r\nSearching for server...\r\n"); if (!bootp()) { printf("No Server found.\r\n"); longjmp(jmp_bootmenu,1); } } printf("My IP %I, Server IP %I, GW IP %I\r\n", arptable[ARP_CLIENT].ipaddr, arptable[ARP_SERVER].ipaddr, arptable[ARP_GATEWAY].ipaddr);#ifdef MDEBUG printf("\n=>>"); getchar();#endif /*** check if have got info from bootp ***/ if (config_buffer[0]) goto cfg_done;#ifndef NO_TFTP /* Now use TFTP to load configuration file */ sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; cfg[17]='\0'; if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done;#endif /* not found; using default values... */ sprintf(config_buffer,"rootfs %I:/usr/diskless_root", arptable[ARP_SERVER].ipaddr); printf("Unable to load config file, guessing:\r\n\t%s\r\n", config_buffer);cfg_done:#ifdef MDEBUG printf("\n=>>"); getchar();#endif p = config_buffer; while(*p) { q = cmd_line; while ((*p != '\n') && (*p)) *(q++) = *(p++); *q = 0; printf("%s\r\n",cmd_line); execute(cmd_line); if (*p) p++; }#ifdef MDEBUG printf("\n=>>"); getchar();#endif /* Check to make sure we've got a rootfs */ if (!arptable[ARP_ROOTSERVER].ipaddr) { printf("No ROOT filesystem server!\r\n"); longjmp(jmp_bootmenu,1); } /* Fill in nfsdiskless.myif */ sprintf(&nfsdiskless.myif.ifra_name,eth_driver); nfsdiskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_addr.sa_family = AF_INET; addr = htonl(arptable[ARP_CLIENT].ipaddr); bcopy(&addr, &nfsdiskless.myif.ifra_addr.sa_data[2], 4); broadcast = (addr & netmask) | ~netmask; nfsdiskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_broadaddr.sa_family = AF_INET; bcopy(&broadcast, &nfsdiskless.myif.ifra_broadaddr.sa_data[2], 4); addr = htonl(arptable[ARP_GATEWAY].ipaddr); if (addr) { nfsdiskless.mygateway.sin_len = sizeof(struct sockaddr); nfsdiskless.mygateway.sin_family = AF_INET; bcopy(&addr, &nfsdiskless.mygateway.sin_addr, 4); } else { nfsdiskless.mygateway.sin_len = 0; } nfsdiskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_mask.sa_family = AF_UNSPEC; bcopy(&netmask, &nfsdiskless.myif.ifra_mask.sa_data[2], 4); rpc_id = currticks(); /* Lookup NFS/MOUNTD ports for SWAP using PORTMAP */ if (arptable[ARP_SWAPSERVER].ipaddr) { char swapfs_fh[32], swapfile[32]; swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2); swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1); if ((swap_nfs_port == -1) || (swap_mount_port == -1)) { printf("Unable to get SWAP NFS/MOUNT ports\r\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port, nfsdiskless.swap_hostnam, &swapfs_fh)) { printf("Unable to mount SWAP filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr); if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port, &swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) { printf("Unable to open %s: ",swapfile); nfs_err(err); longjmp(jmp_bootmenu,1); } if (!nfsdiskless.swap_nblks) { nfsdiskless.swap_nblks = swsize / 1024; printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks); } nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.swap_saddr.sin_family = AF_INET; nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port); nfsdiskless.swap_saddr.sin_addr.s_addr = htonl(arptable[ARP_SWAPSERVER].ipaddr); nfsdiskless.swap_args.timeo = 10; nfsdiskless.swap_args.retrans = 100; } /* Lookup NFS/MOUNTD ports for ROOT using PORTMAP */ root_nfs_port = rpclookup(ARP_ROOTSERVER, PROG_NFS, 2); root_mount_port = rpclookup(ARP_ROOTSERVER, PROG_MOUNT, 1); if ((root_nfs_port == -1) || (root_mount_port == -1)) { printf("Unable to get ROOT NFS/MOUNT ports\r\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_ROOTSERVER, root_mount_port, nfsdiskless.root_hostnam, &nfsdiskless.root_fh)) { printf("Unable to mount ROOT filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } nfsdiskless.root_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.root_saddr.sin_family = AF_INET; nfsdiskless.root_saddr.sin_port = htons(root_nfs_port); nfsdiskless.root_saddr.sin_addr.s_addr = htonl(arptable[ARP_ROOTSERVER].ipaddr); nfsdiskless.root_args.timeo = 10; nfsdiskless.root_args.retrans = 100; nfsdiskless.root_time = 0; if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port, &nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel, &kernel_handle, NULL)) { printf("Unable to open %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } /* Load the kernel using NFS */ printf("Loading %s...\r\n",kernel); if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, 0, sizeof(struct exec), &head)) < 0) { printf("Unable to read %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } if (N_BADMAG(head)) { printf("Bad executable format!\r\n"); longjmp(jmp_bootmenu, 1); } loadpoint = (char *)0x100000; offset = N_TXTOFF(head); printf("text=0x%X, ",head.a_text); nfsload(head.a_text); while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; printf("data=0x%X, ",head.a_data); nfsload(head.a_data); printf("bss=0x%X, ",head.a_bss); while(head.a_bss--) *(loadpoint++) = 0; while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; bootinfo.bi_symtab = (int) loadpoint; p = (char*)&head.a_syms; for (i=0;i<sizeof(head.a_syms);i++) *loadpoint++ = *p++; printf("symbols=[+0x%x+0x%x", sizeof(head.a_syms), head.a_syms); nfsload(head.a_syms); i = sizeof(int); p = loadpoint; nfsload(i); i = *(int*)p; printf("+0x%x]\n", i); i -= sizeof(int); nfsload(i); bootinfo.bi_esymtab = (int) loadpoint; printf("entry=0x%X.\n\r",head.a_entry); /* Jump to kernel */ bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_kernelname = kernel; bootinfo.bi_nfs_diskless = &nfsdiskless; bootinfo.bi_size = sizeof bootinfo; kernelentry = (void *)(head.a_entry & 0x00FFFFFF); (*kernelentry)(howto|RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0); printf("*** %s execute failure ***\n",kernel);}/**************************************************************************POLLKBD - Check for Interrupt from keyboard**************************************************************************/pollkbd(){ if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);}/**************************************************************************DEFAULT_NETMASK - Set a default netmask for IP address**************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -